Added built-in noVNC support.
10
meshuser.js
@ -3431,6 +3431,15 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
node.rdpport = command.rdpport; change = 1; changes.push('rdpport'); // Set the RDP port
|
||||
}
|
||||
}
|
||||
|
||||
if ((typeof command.rfbport == 'number') && (command.rfbport > 0) && (command.rfbport < 65536)) {
|
||||
if ((command.rfbport == 5900) && (node.rfbport != null)) {
|
||||
delete node.rfbport; change = 1; changes.push('rfbport'); // Delete the RFB port
|
||||
} else {
|
||||
node.rfbport = command.rfbport; change = 1; changes.push('rfbport'); // Set the RFB port
|
||||
}
|
||||
}
|
||||
|
||||
if (domain.geolocation && command.userloc && ((node.userloc == null) || (command.userloc[0] != node.userloc[0]) || (command.userloc[1] != node.userloc[1]))) {
|
||||
change = 1;
|
||||
if ((command.userloc.length == 0) && (node.userloc)) {
|
||||
@ -3463,6 +3472,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
event.msg = 'Changed device ' + node.name + ' from group ' + mesh.name + ': ' + changes.join(', ');
|
||||
event.node = parent.CloneSafeNode(node);
|
||||
if (command.rdpport == 3389) { event.node.rdpport = 3389; }
|
||||
if (command.rfbport == 5900) { event.node.rfbport = 5900; }
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come.
|
||||
parent.parent.DispatchEvent(parent.CreateNodeDispatchTargets(node.meshid, node._id, [user._id]), obj, event);
|
||||
}
|
||||
|
68
public/novnc/LICENSE.txt
Normal file
@ -0,0 +1,68 @@
|
||||
noVNC is Copyright (C) 2018 The noVNC Authors
|
||||
(./AUTHORS)
|
||||
|
||||
The noVNC core library files are licensed under the MPL 2.0 (Mozilla
|
||||
Public License 2.0). The noVNC core library is composed of the
|
||||
Javascript code necessary for full noVNC operation. This includes (but
|
||||
is not limited to):
|
||||
|
||||
core/**/*.js
|
||||
app/*.js
|
||||
test/playback.js
|
||||
|
||||
The HTML, CSS, font and images files that included with the noVNC
|
||||
source distibution (or repository) are not considered part of the
|
||||
noVNC core library and are licensed under more permissive licenses.
|
||||
The intent is to allow easy integration of noVNC into existing web
|
||||
sites and web applications.
|
||||
|
||||
The HTML, CSS, font and image files are licensed as follows:
|
||||
|
||||
*.html : 2-Clause BSD license
|
||||
|
||||
app/styles/*.css : 2-Clause BSD license
|
||||
|
||||
app/styles/Orbitron* : SIL Open Font License 1.1
|
||||
(Copyright 2009 Matt McInerney)
|
||||
|
||||
app/images/ : Creative Commons Attribution-ShareAlike
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
Some portions of noVNC are copyright to their individual authors.
|
||||
Please refer to the individual source files and/or to the noVNC commit
|
||||
history: https://github.com/novnc/noVNC/commits/master
|
||||
|
||||
The are several files and projects that have been incorporated into
|
||||
the noVNC core library. Here is a list of those files and the original
|
||||
licenses (all MPL 2.0 compatible):
|
||||
|
||||
core/base64.js : MPL 2.0
|
||||
|
||||
core/des.js : Various BSD style licenses
|
||||
|
||||
vendor/pako/ : MIT
|
||||
|
||||
vendor/browser-es-module-loader/src/ : MIT
|
||||
|
||||
vendor/browser-es-module-loader/dist/ : Various BSD style licenses
|
||||
|
||||
vendor/promise.js : MIT
|
||||
|
||||
Any other files not mentioned above are typically marked with
|
||||
a copyright/license header at the top of the file. The default noVNC
|
||||
license is MPL-2.0.
|
||||
|
||||
The following license texts are included:
|
||||
|
||||
docs/LICENSE.MPL-2.0
|
||||
docs/LICENSE.OFL-1.1
|
||||
docs/LICENSE.BSD-3-Clause (New BSD)
|
||||
docs/LICENSE.BSD-2-Clause (Simplified BSD / FreeBSD)
|
||||
vendor/pako/LICENSE (MIT)
|
||||
|
||||
Or alternatively the license texts may be found here:
|
||||
|
||||
http://www.mozilla.org/MPL/2.0/
|
||||
http://scripts.sil.org/OFL
|
||||
http://en.wikipedia.org/wiki/BSD_licenses
|
||||
https://opensource.org/licenses/MIT
|
58
public/novnc/app/error-handler.js
Normal file
@ -0,0 +1,58 @@
|
||||
// NB: this should *not* be included as a module until we have
|
||||
// native support in the browsers, so that our error handler
|
||||
// can catch script-loading errors.
|
||||
|
||||
// No ES6 can be used in this file since it's used for the translation
|
||||
/* eslint-disable prefer-arrow-callback */
|
||||
|
||||
(function _scope() {
|
||||
"use strict";
|
||||
|
||||
// Fallback for all uncought errors
|
||||
function handleError(event, err) {
|
||||
try {
|
||||
const msg = document.getElementById('noVNC_fallback_errormsg');
|
||||
|
||||
// Only show the initial error
|
||||
if (msg.hasChildNodes()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let div = document.createElement("div");
|
||||
div.classList.add('noVNC_message');
|
||||
div.appendChild(document.createTextNode(event.message));
|
||||
msg.appendChild(div);
|
||||
|
||||
if (event.filename) {
|
||||
div = document.createElement("div");
|
||||
div.className = 'noVNC_location';
|
||||
let text = event.filename;
|
||||
if (event.lineno !== undefined) {
|
||||
text += ":" + event.lineno;
|
||||
if (event.colno !== undefined) {
|
||||
text += ":" + event.colno;
|
||||
}
|
||||
}
|
||||
div.appendChild(document.createTextNode(text));
|
||||
msg.appendChild(div);
|
||||
}
|
||||
|
||||
if (err && err.stack) {
|
||||
div = document.createElement("div");
|
||||
div.className = 'noVNC_stack';
|
||||
div.appendChild(document.createTextNode(err.stack));
|
||||
msg.appendChild(div);
|
||||
}
|
||||
|
||||
document.getElementById('noVNC_fallback_error')
|
||||
.classList.add("noVNC_open");
|
||||
} catch (exc) {
|
||||
document.write("noVNC encountered an error.");
|
||||
}
|
||||
// Don't return true since this would prevent the error
|
||||
// from being printed to the browser console.
|
||||
return false;
|
||||
}
|
||||
window.addEventListener('error', function onerror(evt) { handleError(evt, evt.error); });
|
||||
window.addEventListener('unhandledrejection', function onreject(evt) { handleError(evt.reason, evt.reason); });
|
||||
})();
|
92
public/novnc/app/images/alt.svg
Normal file
@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="alt.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="16"
|
||||
inkscape:cx="18.205425"
|
||||
inkscape:cy="17.531398"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<g
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:48px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="text5290">
|
||||
<path
|
||||
d="m 9.9560547,1042.3329 -2.9394531,0 -0.4638672,1.3281 -1.8896485,0 2.7001953,-7.29 2.241211,0 2.7001958,7.29 -1.889649,0 -0.4589843,-1.3281 z m -2.4707031,-1.3526 1.9970703,0 -0.9960938,-2.9003 -1.0009765,2.9003 z"
|
||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
||||
id="path5340" />
|
||||
<path
|
||||
d="m 13.188477,1036.0634 1.748046,0 0,7.5976 -1.748046,0 0,-7.5976 z"
|
||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
||||
id="path5342" />
|
||||
<path
|
||||
d="m 18.535156,1036.6395 0,1.5528 1.801758,0 0,1.25 -1.801758,0 0,2.3193 q 0,0.3809 0.151367,0.5176 0.151368,0.1318 0.600586,0.1318 l 0.898438,0 0,1.25 -1.499024,0 q -1.035156,0 -1.469726,-0.4297 -0.429688,-0.4345 -0.429688,-1.4697 l 0,-2.3193 -0.86914,0 0,-1.25 0.86914,0 0,-1.5528 1.748047,0 z"
|
||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
||||
id="path5344" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
106
public/novnc/app/images/clipboard.svg
Normal file
@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="clipboard.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="15.366606"
|
||||
inkscape:cy="16.42981"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<path
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="M 9,6 6,6 C 5.4459889,6 5,6.4459889 5,7 l 0,13 c 0,0.554011 0.4459889,1 1,1 l 13,0 c 0.554011,0 1,-0.445989 1,-1 L 20,7 C 20,6.4459889 19.554011,6 19,6 l -3,0"
|
||||
transform="translate(0,1027.3622)"
|
||||
id="rect6083"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cssssssssc" />
|
||||
<rect
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect6085"
|
||||
width="7"
|
||||
height="4"
|
||||
x="9"
|
||||
y="1031.3622"
|
||||
ry="1.00002" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081"
|
||||
d="m 8.5071212,1038.8622 7.9999998,0"
|
||||
id="path6087"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081"
|
||||
d="m 8.5071212,1041.8622 3.9999998,0"
|
||||
id="path6089"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081"
|
||||
d="m 8.5071212,1044.8622 5.9999998,0"
|
||||
id="path6091"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.9 KiB |
96
public/novnc/app/images/connect.svg
Normal file
@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="connect.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="37.14834"
|
||||
inkscape:cy="1.9525926"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<g
|
||||
id="g5103"
|
||||
transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,-729.15757,315.8823)">
|
||||
<path
|
||||
sodipodi:nodetypes="cssssc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect5096"
|
||||
d="m 11,1040.3622 -5,0 c -1.108,0 -2,-0.892 -2,-2 l 0,-4 c 0,-1.108 0.892,-2 2,-2 l 5,0"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<path
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 14,1032.3622 5,0 c 1.108,0 2,0.892 2,2 l 0,4 c 0,1.108 -0.892,2 -2,2 l -5,0"
|
||||
id="path5099"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cssssc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5101"
|
||||
d="m 9,1036.3622 7,0"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.3 KiB |
96
public/novnc/app/images/ctrl.svg
Normal file
@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="ctrl.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="16"
|
||||
inkscape:cx="18.205425"
|
||||
inkscape:cy="17.531398"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<g
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:48px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="text5290">
|
||||
<path
|
||||
d="m 9.1210938,1043.1898 q -0.5175782,0.2686 -1.0791016,0.4053 -0.5615235,0.1367 -1.171875,0.1367 -1.8212891,0 -2.8857422,-1.0156 -1.0644531,-1.0205 -1.0644531,-2.7637 0,-1.748 1.0644531,-2.7637 1.0644531,-1.0205 2.8857422,-1.0205 0.6103515,0 1.171875,0.1368 0.5615234,0.1367 1.0791016,0.4052 l 0,1.5088 q -0.522461,-0.3564 -1.0302735,-0.5224 -0.5078125,-0.1661 -1.0693359,-0.1661 -1.0058594,0 -1.5820313,0.6446 -0.5761719,0.6445 -0.5761719,1.7773 0,1.1279 0.5761719,1.7725 0.5761719,0.6445 1.5820313,0.6445 0.5615234,0 1.0693359,-0.166 0.5078125,-0.166 1.0302735,-0.5225 l 0,1.5088 z"
|
||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
||||
id="path5370" />
|
||||
<path
|
||||
d="m 12.514648,1036.5687 0,1.5528 1.801758,0 0,1.25 -1.801758,0 0,2.3193 q 0,0.3809 0.151368,0.5176 0.151367,0.1318 0.600586,0.1318 l 0.898437,0 0,1.25 -1.499023,0 q -1.035157,0 -1.469727,-0.4297 -0.429687,-0.4345 -0.429687,-1.4697 l 0,-2.3193 -0.8691411,0 0,-1.25 0.8691411,0 0,-1.5528 1.748046,0 z"
|
||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
||||
id="path5372" />
|
||||
<path
|
||||
d="m 19.453125,1039.6107 q -0.229492,-0.1074 -0.458984,-0.1562 -0.22461,-0.054 -0.454102,-0.054 -0.673828,0 -1.040039,0.4345 -0.361328,0.4297 -0.361328,1.2354 l 0,2.5195 -1.748047,0 0,-5.4687 1.748047,0 0,0.8984 q 0.336914,-0.5371 0.771484,-0.7813 0.439453,-0.249 1.049805,-0.249 0.08789,0 0.19043,0.01 0.102539,0 0.297851,0.029 l 0.0049,1.582 z"
|
||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
||||
id="path5374" />
|
||||
<path
|
||||
d="m 20.332031,1035.9926 1.748047,0 0,7.5976 -1.748047,0 0,-7.5976 z"
|
||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
||||
id="path5376" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
100
public/novnc/app/images/ctrlaltdel.svg
Normal file
@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="ctrlaltdel.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="8"
|
||||
inkscape:cx="11.135667"
|
||||
inkscape:cy="16.407428"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<rect
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect5253"
|
||||
width="5"
|
||||
height="5.0000172"
|
||||
x="16"
|
||||
y="1031.3622"
|
||||
ry="1.0000174" />
|
||||
<rect
|
||||
y="1043.3622"
|
||||
x="4"
|
||||
height="5.0000172"
|
||||
width="5"
|
||||
id="rect5255"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
ry="1.0000174" />
|
||||
<rect
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect5257"
|
||||
width="5"
|
||||
height="5.0000172"
|
||||
x="13"
|
||||
y="1043.3622"
|
||||
ry="1.0000174" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.2 KiB |
94
public/novnc/app/images/disconnect.svg
Normal file
@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="disconnect.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="16"
|
||||
inkscape:cx="25.05707"
|
||||
inkscape:cy="11.594858"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<g
|
||||
id="g5171"
|
||||
transform="translate(-24.062499,-6.15775e-4)">
|
||||
<path
|
||||
id="path5110"
|
||||
transform="translate(0,1027.3622)"
|
||||
d="m 39.744141,3.4960938 c -0.769923,0 -1.539607,0.2915468 -2.121094,0.8730468 l -2.566406,2.5664063 1.414062,1.4140625 2.566406,-2.5664063 c 0.403974,-0.404 1.010089,-0.404 1.414063,0 l 2.828125,2.828125 c 0.40398,0.4039 0.403907,1.0101621 0,1.4140629 l -2.566406,2.566406 1.414062,1.414062 2.566406,-2.566406 c 1.163041,-1.1629 1.162968,-3.0791874 0,-4.2421874 L 41.865234,4.3691406 C 41.283747,3.7876406 40.514063,3.4960937 39.744141,3.4960938 Z M 39.017578,9.015625 a 1.0001,1.0001 0 0 0 -0.6875,0.3027344 l -0.445312,0.4453125 1.414062,1.4140621 0.445313,-0.445312 A 1.0001,1.0001 0 0 0 39.017578,9.015625 Z m -6.363281,0.7070312 a 1.0001,1.0001 0 0 0 -0.6875,0.3027348 L 28.431641,13.5625 c -1.163042,1.163 -1.16297,3.079187 0,4.242188 l 2.828125,2.828124 c 1.162974,1.163101 3.079213,1.163101 4.242187,0 l 3.535156,-3.535156 a 1.0001,1.0001 0 1 0 -1.414062,-1.414062 l -3.535156,3.535156 c -0.403974,0.404 -1.010089,0.404 -1.414063,0 l -2.828125,-2.828125 c -0.403981,-0.404 -0.403908,-1.010162 0,-1.414063 l 3.535156,-3.537109 A 1.0001,1.0001 0 0 0 32.654297,9.7226562 Z m 3.109375,2.1621098 -2.382813,2.384765 a 1.0001,1.0001 0 1 0 1.414063,1.414063 l 2.382812,-2.384766 -1.414062,-1.414062 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,0,0)"
|
||||
y="752.29541"
|
||||
x="-712.31262"
|
||||
height="18.000017"
|
||||
width="3"
|
||||
id="rect5116"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.9 KiB |
76
public/novnc/app/images/drag.svg
Normal file
@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="drag.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="9.8789407"
|
||||
inkscape:cy="9.5008608"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<path
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 7.039733,1049.3037 c -0.4309106,-0.1233 -0.7932634,-0.4631 -0.9705434,-0.9103 -0.04922,-0.1241 -0.057118,-0.2988 -0.071321,-1.5771 l -0.015972,-1.4375 -0.328125,-0.082 c -0.7668138,-0.1927 -1.1897046,-0.4275 -1.7031253,-0.9457 -0.4586773,-0.4629 -0.6804297,-0.8433 -0.867034,-1.4875 -0.067215,-0.232 -0.068001,-0.2642 -0.078682,-3.2188 -0.012078,-3.341 -0.020337,-3.2012 0.2099452,-3.5555 0.2246623,-0.3458 0.5798271,-0.5892 0.9667343,-0.6626 0.092506,-0.017 0.531898,-0.032 0.9764271,-0.032 l 0.8082347,0 1.157e-4,1.336 c 1.125e-4,1.2779 0.00281,1.3403 0.062214,1.4378 0.091785,0.1505 0.2357707,0.226 0.4314082,0.2261 0.285389,2e-4 0.454884,-0.1352 0.5058962,-0.4042 0.019355,-0.102 0.031616,-0.982 0.031616,-2.269 0,-1.9756 0.00357,-2.1138 0.059205,-2.2926 0.1645475,-0.5287 0.6307616,-0.9246 1.19078,-1.0113 0.8000572,-0.1238 1.5711277,0.4446 1.6860387,1.2429 0.01732,0.1203 0.03177,0.8248 0.03211,1.5657 6.19e-4,1.3449 7.22e-4,1.347 0.07093,1.4499 0.108355,0.1587 0.255268,0.2248 0.46917,0.2108 0.204069,-0.013 0.316116,-0.08 0.413642,-0.2453 0.06028,-0.1024 0.06307,-0.1778 0.07862,-2.1218 0.01462,-1.8283 0.02124,-2.0285 0.07121,-2.1549 0.260673,-0.659 0.934894,-1.0527 1.621129,-0.9465 0.640523,0.099 1.152269,0.6104 1.243187,1.2421 0.01827,0.1269 0.03175,0.9943 0.03211,2.0657 l 6.19e-4,1.8469 0.07031,0.103 c 0.108355,0.1587 0.255267,0.2248 0.46917,0.2108 0.204069,-0.013 0.316115,-0.08 0.413642,-0.2453 0.05951,-0.1011 0.06329,-0.1786 0.07907,-1.6218 0.01469,-1.3438 0.02277,-1.5314 0.07121,-1.6549 0.257975,-0.6576 0.934425,-1.0527 1.620676,-0.9465 0.640522,0.099 1.152269,0.6104 1.243186,1.2421 0.0186,0.1292 0.03179,1.0759 0.03222,2.3125 7.15e-4,2.0335 0.0025,2.0966 0.06283,2.1956 0.09178,0.1505 0.235771,0.226 0.431409,0.2261 0.285388,2e-4 0.454884,-0.1352 0.505897,-0.4042 0.01874,-0.099 0.03161,-0.8192 0.03161,-1.769 0,-1.4848 0.0043,-1.6163 0.0592,-1.7926 0.164548,-0.5287 0.630762,-0.9246 1.19078,-1.0113 0.800057,-0.1238 1.571128,0.4446 1.686039,1.2429 0.04318,0.2999 0.04372,9.1764 5.78e-4,9.4531 -0.04431,0.2841 -0.217814,0.6241 -0.420069,0.8232 -0.320102,0.315 -0.63307,0.4268 -1.194973,0.4268 l -0.35281,0 -2.51e-4,1.2734 c -1.25e-4,0.7046 -0.01439,1.3642 -0.03191,1.4766 -0.06665,0.4274 -0.372966,0.8704 -0.740031,1.0702 -0.349999,0.1905 0.01748,0.18 -6.242199,0.1776 -5.3622439,0 -5.7320152,-0.01 -5.9121592,-0.057 l 1.4e-5,0 z"
|
||||
id="path4379"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.6 KiB |
81
public/novnc/app/images/error.svg
Normal file
@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="error.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="14.00357"
|
||||
inkscape:cy="12.443398"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<path
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="M 7 3 C 4.7839905 3 3 4.7839905 3 7 L 3 18 C 3 20.21601 4.7839905 22 7 22 L 18 22 C 20.21601 22 22 20.21601 22 18 L 22 7 C 22 4.7839905 20.21601 3 18 3 L 7 3 z M 7.6992188 6 A 1.6916875 1.6924297 0 0 1 8.9121094 6.5117188 L 12.5 10.101562 L 16.087891 6.5117188 A 1.6916875 1.6924297 0 0 1 17.251953 6 A 1.6916875 1.6924297 0 0 1 18.480469 8.90625 L 14.892578 12.496094 L 18.480469 16.085938 A 1.6916875 1.6924297 0 1 1 16.087891 18.478516 L 12.5 14.888672 L 8.9121094 18.478516 A 1.6916875 1.6924297 0 1 1 6.5214844 16.085938 L 10.109375 12.496094 L 6.5214844 8.90625 A 1.6916875 1.6924297 0 0 1 7.6992188 6 z "
|
||||
transform="translate(0,1027.3622)"
|
||||
id="rect4135" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.0 KiB |
92
public/novnc/app/images/esc.svg
Normal file
@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="esc.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="16"
|
||||
inkscape:cx="18.205425"
|
||||
inkscape:cy="17.531398"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="text5290"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<g
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:48px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="text5290">
|
||||
<path
|
||||
d="m 3.9331055,1036.1464 5.0732422,0 0,1.4209 -3.1933594,0 0,1.3574 3.0029297,0 0,1.4209 -3.0029297,0 0,1.6699 3.3007812,0 0,1.4209 -5.180664,0 0,-7.29 z"
|
||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
||||
id="path5314" />
|
||||
<path
|
||||
d="m 14.963379,1038.1385 0,1.3282 q -0.561524,-0.2344 -1.083984,-0.3516 -0.522461,-0.1172 -0.986329,-0.1172 -0.498046,0 -0.742187,0.127 -0.239258,0.122 -0.239258,0.3808 0,0.21 0.180664,0.3223 0.185547,0.1123 0.65918,0.166 l 0.307617,0.044 q 1.342773,0.1709 1.806641,0.5615 0.463867,0.3906 0.463867,1.2256 0,0.874 -0.644531,1.3134 -0.644532,0.4395 -1.923829,0.4395 -0.541992,0 -1.123046,-0.088 -0.576172,-0.083 -1.186524,-0.2539 l 0,-1.3281 q 0.522461,0.2539 1.069336,0.3808 0.551758,0.127 1.118164,0.127 0.512695,0 0.771485,-0.1416 0.258789,-0.1416 0.258789,-0.4199 0,-0.2344 -0.180664,-0.3467 -0.175782,-0.1172 -0.708008,-0.1807 l -0.307617,-0.039 q -1.166993,-0.1465 -1.635743,-0.542 -0.46875,-0.3955 -0.46875,-1.2012 0,-0.8691 0.595703,-1.2891 0.595704,-0.4199 1.826172,-0.4199 0.483399,0 1.015625,0.073 0.532227,0.073 1.157227,0.2294 z"
|
||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
||||
id="path5316" />
|
||||
<path
|
||||
d="m 21.066895,1038.1385 0,1.4258 q -0.356446,-0.2441 -0.717774,-0.3613 -0.356445,-0.1172 -0.742187,-0.1172 -0.732422,0 -1.142579,0.4297 -0.405273,0.4248 -0.405273,1.1914 0,0.7666 0.405273,1.1963 0.410157,0.4248 1.142579,0.4248 0.410156,0 0.776367,-0.1221 0.371094,-0.122 0.683594,-0.3613 l 0,1.4307 q -0.410157,0.1513 -0.834961,0.2246 -0.419922,0.078 -0.844727,0.078 -1.479492,0 -2.314453,-0.7568 -0.834961,-0.7618 -0.834961,-2.1143 0,-1.3525 0.834961,-2.1094 0.834961,-0.7617 2.314453,-0.7617 0.429688,0 0.844727,0.078 0.419921,0.073 0.834961,0.2246 z"
|
||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
||||
id="path5318" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.4 KiB |
69
public/novnc/app/images/expander.svg
Normal file
@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="9"
|
||||
height="10"
|
||||
viewBox="0 0 9 10"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="expander.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="45.254834"
|
||||
inkscape:cx="9.8737281"
|
||||
inkscape:cy="6.4583132"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:snap-object-midpoints="false"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1042.3622)">
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="M 2.0800781,1042.3633 A 2.0002,2.0002 0 0 0 0,1044.3613 l 0,6 a 2.0002,2.0002 0 0 0 3.0292969,1.7168 l 5,-3 a 2.0002,2.0002 0 0 0 0,-3.4316 l -5,-3 a 2.0002,2.0002 0 0 0 -0.9492188,-0.2832 z"
|
||||
id="path4138"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.0 KiB |
93
public/novnc/app/images/fullscreen.svg
Normal file
@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="fullscreen.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="16.400723"
|
||||
inkscape:cy="15.083758"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<rect
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect5006"
|
||||
width="17"
|
||||
height="17.000017"
|
||||
x="4"
|
||||
y="1031.3622"
|
||||
ry="3.0000174" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 7.5,1044.8622 4,0 -1.5,-1.5 1.5,-1.5 -1,-1 -1.5,1.5 -1.5,-1.5 0,4 z"
|
||||
id="path5017"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5025"
|
||||
d="m 17.5,1034.8622 -4,0 1.5,1.5 -1.5,1.5 1,1 1.5,-1.5 1.5,1.5 0,-4 z"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
82
public/novnc/app/images/handle.svg
Normal file
@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="5"
|
||||
height="6"
|
||||
viewBox="0 0 5 6"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="handle.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="32"
|
||||
inkscape:cx="1.3551778"
|
||||
inkscape:cy="8.7800329"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1046.3622)">
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 4.0000803,1049.3622 -3,-2 0,4 z"
|
||||
id="path4247"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
172
public/novnc/app/images/handle_bg.svg
Normal file
@ -0,0 +1,172 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="15"
|
||||
height="50"
|
||||
viewBox="0 0 15 50"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="handle_bg.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="16"
|
||||
inkscape:cx="-10.001409"
|
||||
inkscape:cy="24.512566"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1002.3622)">
|
||||
<rect
|
||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4249"
|
||||
width="1"
|
||||
height="1.0000174"
|
||||
x="9.5"
|
||||
y="1008.8622"
|
||||
ry="1.7382812e-05" />
|
||||
<rect
|
||||
ry="1.7382812e-05"
|
||||
y="1013.8622"
|
||||
x="9.5"
|
||||
height="1.0000174"
|
||||
width="1"
|
||||
id="rect4255"
|
||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
ry="1.7382812e-05"
|
||||
y="1008.8622"
|
||||
x="4.5"
|
||||
height="1.0000174"
|
||||
width="1"
|
||||
id="rect4261"
|
||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4263"
|
||||
width="1"
|
||||
height="1.0000174"
|
||||
x="4.5"
|
||||
y="1013.8622"
|
||||
ry="1.7382812e-05" />
|
||||
<rect
|
||||
ry="1.7382812e-05"
|
||||
y="1039.8622"
|
||||
x="9.5"
|
||||
height="1.0000174"
|
||||
width="1"
|
||||
id="rect4265"
|
||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4267"
|
||||
width="1"
|
||||
height="1.0000174"
|
||||
x="9.5"
|
||||
y="1044.8622"
|
||||
ry="1.7382812e-05" />
|
||||
<rect
|
||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4269"
|
||||
width="1"
|
||||
height="1.0000174"
|
||||
x="4.5"
|
||||
y="1039.8622"
|
||||
ry="1.7382812e-05" />
|
||||
<rect
|
||||
ry="1.7382812e-05"
|
||||
y="1044.8622"
|
||||
x="4.5"
|
||||
height="1.0000174"
|
||||
width="1"
|
||||
id="rect4271"
|
||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4273"
|
||||
width="1"
|
||||
height="1.0000174"
|
||||
x="9.5"
|
||||
y="1018.8622"
|
||||
ry="1.7382812e-05" />
|
||||
<rect
|
||||
ry="1.7382812e-05"
|
||||
y="1018.8622"
|
||||
x="4.5"
|
||||
height="1.0000174"
|
||||
width="1"
|
||||
id="rect4275"
|
||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4277"
|
||||
width="1"
|
||||
height="1.0000174"
|
||||
x="9.5"
|
||||
y="1034.8622"
|
||||
ry="1.7382812e-05" />
|
||||
<rect
|
||||
ry="1.7382812e-05"
|
||||
y="1034.8622"
|
||||
x="4.5"
|
||||
height="1.0000174"
|
||||
width="1"
|
||||
id="rect4279"
|
||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.2 KiB |
81
public/novnc/app/images/info.svg
Normal file
@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="info.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="15.720838"
|
||||
inkscape:cy="8.9111233"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<path
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="M 12.5 3 A 9.5 9.4999914 0 0 0 3 12.5 A 9.5 9.4999914 0 0 0 12.5 22 A 9.5 9.4999914 0 0 0 22 12.5 A 9.5 9.4999914 0 0 0 12.5 3 z M 12.5 5 A 1.5 1.5000087 0 0 1 14 6.5 A 1.5 1.5000087 0 0 1 12.5 8 A 1.5 1.5000087 0 0 1 11 6.5 A 1.5 1.5000087 0 0 1 12.5 5 z M 10.521484 8.9785156 L 12.521484 8.9785156 A 1.50015 1.50015 0 0 1 14.021484 10.478516 L 14.021484 15.972656 A 1.50015 1.50015 0 0 1 14.498047 18.894531 C 14.498047 18.894531 13.74301 19.228309 12.789062 18.912109 C 12.312092 18.754109 11.776235 18.366625 11.458984 17.828125 C 11.141734 17.289525 11.021484 16.668469 11.021484 15.980469 L 11.021484 11.980469 L 10.521484 11.980469 A 1.50015 1.50015 0 1 1 10.521484 8.9804688 L 10.521484 8.9785156 z "
|
||||
transform="translate(0,1027.3622)"
|
||||
id="path4136" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
88
public/novnc/app/images/keyboard.svg
Normal file
@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="keyboard.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/keyboard.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#717171"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="31.285341"
|
||||
inkscape:cy="8.8028469"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:snap-bbox-midpoints="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:object-paths="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-midpoints="true"
|
||||
inkscape:snap-smooth-nodes="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="M 7,3 C 4.8012876,3 3,4.8013 3,7 3,11.166667 3,15.333333 3,19.5 3,20.8764 4.1236413,22 5.5,22 l 14,0 C 20.876358,22 22,20.8764 22,19.5 22,15.333333 22,11.166667 22,7 22,4.8013 20.198712,3 18,3 Z m 0,2 11,0 c 1.125307,0 2,0.8747 2,2 L 20,12 5,12 5,7 C 5,5.8747 5.8746931,5 7,5 Z M 6.5,14 C 6.777,14 7,14.223 7,14.5 7,14.777 6.777,15 6.5,15 6.223,15 6,14.777 6,14.5 6,14.223 6.223,14 6.5,14 Z m 2,0 C 8.777,14 9,14.223 9,14.5 9,14.777 8.777,15 8.5,15 8.223,15 8,14.777 8,14.5 8,14.223 8.223,14 8.5,14 Z m 2,0 C 10.777,14 11,14.223 11,14.5 11,14.777 10.777,15 10.5,15 10.223,15 10,14.777 10,14.5 10,14.223 10.223,14 10.5,14 Z m 2,0 C 12.777,14 13,14.223 13,14.5 13,14.777 12.777,15 12.5,15 12.223,15 12,14.777 12,14.5 12,14.223 12.223,14 12.5,14 Z m 2,0 C 14.777,14 15,14.223 15,14.5 15,14.777 14.777,15 14.5,15 14.223,15 14,14.777 14,14.5 14,14.223 14.223,14 14.5,14 Z m 2,0 C 16.777,14 17,14.223 17,14.5 17,14.777 16.777,15 16.5,15 16.223,15 16,14.777 16,14.5 16,14.223 16.223,14 16.5,14 Z m 2,0 C 18.777,14 19,14.223 19,14.5 19,14.777 18.777,15 18.5,15 18.223,15 18,14.777 18,14.5 18,14.223 18.223,14 18.5,14 Z m -13,2 C 5.777,16 6,16.223 6,16.5 6,16.777 5.777,17 5.5,17 5.223,17 5,16.777 5,16.5 5,16.223 5.223,16 5.5,16 Z m 2,0 C 7.777,16 8,16.223 8,16.5 8,16.777 7.777,17 7.5,17 7.223,17 7,16.777 7,16.5 7,16.223 7.223,16 7.5,16 Z m 2,0 C 9.777,16 10,16.223 10,16.5 10,16.777 9.777,17 9.5,17 9.223,17 9,16.777 9,16.5 9,16.223 9.223,16 9.5,16 Z m 2,0 C 11.777,16 12,16.223 12,16.5 12,16.777 11.777,17 11.5,17 11.223,17 11,16.777 11,16.5 11,16.223 11.223,16 11.5,16 Z m 2,0 C 13.777,16 14,16.223 14,16.5 14,16.777 13.777,17 13.5,17 13.223,17 13,16.777 13,16.5 13,16.223 13.223,16 13.5,16 Z m 2,0 C 15.777,16 16,16.223 16,16.5 16,16.777 15.777,17 15.5,17 15.223,17 15,16.777 15,16.5 15,16.223 15.223,16 15.5,16 Z m 2,0 C 17.777,16 18,16.223 18,16.5 18,16.777 17.777,17 17.5,17 17.223,17 17,16.777 17,16.5 17,16.223 17.223,16 17.5,16 Z m 2,0 C 19.777,16 20,16.223 20,16.5 20,16.777 19.777,17 19.5,17 19.223,17 19,16.777 19,16.5 19,16.223 19.223,16 19.5,16 Z M 6,18 c 0.554,0 1,0.446 1,1 0,0.554 -0.446,1 -1,1 -0.554,0 -1,-0.446 -1,-1 0,-0.554 0.446,-1 1,-1 z m 2.8261719,0 7.3476561,0 C 16.631643,18 17,18.368372 17,18.826172 l 0,0.347656 C 17,19.631628 16.631643,20 16.173828,20 L 8.8261719,20 C 8.3683573,20 8,19.631628 8,19.173828 L 8,18.826172 C 8,18.368372 8.3683573,18 8.8261719,18 Z m 10.1113281,0 0.125,0 C 19.581551,18 20,18.4184 20,18.9375 l 0,0.125 C 20,19.5816 19.581551,20 19.0625,20 l -0.125,0 C 18.418449,20 18,19.5816 18,19.0625 l 0,-0.125 C 18,18.4184 18.418449,18 18.9375,18 Z"
|
||||
transform="translate(0,1027.3622)"
|
||||
id="rect4160"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="sccssccsssssccssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 12.499929,1033.8622 -2,2 1.500071,0 0,2 1,0 0,-2 1.499929,0 z"
|
||||
id="path4150"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.3 KiB |
92
public/novnc/app/images/mouse_left.svg
Normal file
@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="mouse_left.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.313708"
|
||||
inkscape:cx="15.551515"
|
||||
inkscape:cy="12.205592"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#0068f6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 8,1030.3622 c -2.1987124,0 -4,1.8013 -4,4 l 0,2 5,0 0,-2 c 0,-1.4738 1.090393,-2.7071 2.5,-2.9492 l 0,-1.0508 -3.5,0 z"
|
||||
id="path6219" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 13.5,1030.3622 0,1.0508 c 1.409607,0.2421 2.5,1.4754 2.5,2.9492 l 0,2 5,0 0,-2 c 0,-2.1987 -1.801288,-4 -4,-4 l -3.5,0 z"
|
||||
id="path6217" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 12,1033.3622 c -0.571311,0 -1,0.4287 -1,1 l 0,5 c 0,0.5713 0.428689,1 1,1 l 1,0 c 0.571311,0 1,-0.4287 1,-1 l 0,-5 c 0,-0.5713 -0.428689,-1 -1,-1 l -1,0 z"
|
||||
id="path6215" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 4,1038.3622 0,3.5 c 0,4.1377 3.362302,7.5 7.5,7.5 l 2,0 c 4.137698,0 7.5,-3.3623 7.5,-7.5 l 0,-3.5 -5,0 0,1 c 0,1.6447 -1.355293,3 -3,3 l -1,0 c -1.644707,0 -3,-1.3553 -3,-3 l 0,-1 -5,0 z"
|
||||
id="rect6178" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.8 KiB |
92
public/novnc/app/images/mouse_middle.svg
Normal file
@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="mouse_middle.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.313708"
|
||||
inkscape:cx="15.551515"
|
||||
inkscape:cy="12.205592"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 8,1030.3622 c -2.1987124,0 -4,1.8013 -4,4 l 0,2 5,0 0,-2 c 0,-1.4738 1.090393,-2.7071 2.5,-2.9492 l 0,-1.0508 -3.5,0 z"
|
||||
id="path6219" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 13.5,1030.3622 0,1.0508 c 1.409607,0.2421 2.5,1.4754 2.5,2.9492 l 0,2 5,0 0,-2 c 0,-2.1987 -1.801288,-4 -4,-4 l -3.5,0 z"
|
||||
id="path6217" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#0068f6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 12,1033.3622 c -0.571311,0 -1,0.4287 -1,1 l 0,5 c 0,0.5713 0.428689,1 1,1 l 1,0 c 0.571311,0 1,-0.4287 1,-1 l 0,-5 c 0,-0.5713 -0.428689,-1 -1,-1 l -1,0 z"
|
||||
id="path6215" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 4,1038.3622 0,3.5 c 0,4.1377 3.362302,7.5 7.5,7.5 l 2,0 c 4.137698,0 7.5,-3.3623 7.5,-7.5 l 0,-3.5 -5,0 0,1 c 0,1.6447 -1.355293,3 -3,3 l -1,0 c -1.644707,0 -3,-1.3553 -3,-3 l 0,-1 -5,0 z"
|
||||
id="rect6178" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.8 KiB |
92
public/novnc/app/images/mouse_none.svg
Normal file
@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="mouse_none.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="16"
|
||||
inkscape:cx="23.160825"
|
||||
inkscape:cy="13.208262"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 8,1030.3622 c -2.1987124,0 -4,1.8013 -4,4 l 0,2 5,0 0,-2 c 0,-1.4738 1.090393,-2.7071 2.5,-2.9492 l 0,-1.0508 -3.5,0 z"
|
||||
id="path6219" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 13.5,1030.3622 0,1.0508 c 1.409607,0.2421 2.5,1.4754 2.5,2.9492 l 0,2 5,0 0,-2 c 0,-2.1987 -1.801288,-4 -4,-4 l -3.5,0 z"
|
||||
id="path6217" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 12,1033.3622 c -0.571311,0 -1,0.4287 -1,1 l 0,5 c 0,0.5713 0.428689,1 1,1 l 1,0 c 0.571311,0 1,-0.4287 1,-1 l 0,-5 c 0,-0.5713 -0.428689,-1 -1,-1 l -1,0 z"
|
||||
id="path6215" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 4,1038.3622 0,3.5 c 0,4.1377 3.362302,7.5 7.5,7.5 l 2,0 c 4.137698,0 7.5,-3.3623 7.5,-7.5 l 0,-3.5 -5,0 0,1 c 0,1.6447 -1.355293,3 -3,3 l -1,0 c -1.644707,0 -3,-1.3553 -3,-3 l 0,-1 -5,0 z"
|
||||
id="rect6178" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.8 KiB |
92
public/novnc/app/images/mouse_right.svg
Normal file
@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="mouse_right.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.313708"
|
||||
inkscape:cx="15.551515"
|
||||
inkscape:cy="12.205592"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 8,1030.3622 c -2.1987124,0 -4,1.8013 -4,4 l 0,2 5,0 0,-2 c 0,-1.4738 1.090393,-2.7071 2.5,-2.9492 l 0,-1.0508 -3.5,0 z"
|
||||
id="path6219" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#0068f6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 13.5,1030.3622 0,1.0508 c 1.409607,0.2421 2.5,1.4754 2.5,2.9492 l 0,2 5,0 0,-2 c 0,-2.1987 -1.801288,-4 -4,-4 l -3.5,0 z"
|
||||
id="path6217" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 12,1033.3622 c -0.571311,0 -1,0.4287 -1,1 l 0,5 c 0,0.5713 0.428689,1 1,1 l 1,0 c 0.571311,0 1,-0.4287 1,-1 l 0,-5 c 0,-0.5713 -0.428689,-1 -1,-1 l -1,0 z"
|
||||
id="path6215" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 4,1038.3622 0,3.5 c 0,4.1377 3.362302,7.5 7.5,7.5 l 2,0 c 4.137698,0 7.5,-3.3623 7.5,-7.5 l 0,-3.5 -5,0 0,1 c 0,1.6447 -1.355293,3 -3,3 l -1,0 c -1.644707,0 -3,-1.3553 -3,-3 l 0,-1 -5,0 z"
|
||||
id="rect6178" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.8 KiB |
87
public/novnc/app/images/power.svg
Normal file
@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="power.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="9.3159849"
|
||||
inkscape:cy="13.436208"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="M 9 6.8183594 C 6.3418164 8.1213032 4.5 10.849161 4.5 14 C 4.5 18.4065 8.0935666 22 12.5 22 C 16.906433 22 20.5 18.4065 20.5 14 C 20.5 10.849161 18.658184 8.1213032 16 6.8183594 L 16 9.125 C 17.514327 10.211757 18.5 11.984508 18.5 14 C 18.5 17.3256 15.825553 20 12.5 20 C 9.1744469 20 6.5 17.3256 6.5 14 C 6.5 11.984508 7.4856727 10.211757 9 9.125 L 9 6.8183594 z "
|
||||
transform="translate(0,1027.3622)"
|
||||
id="path6140" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 12.5,1031.8836 0,6.4786"
|
||||
id="path6142"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.9 KiB |
76
public/novnc/app/images/settings.svg
Normal file
@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="settings.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="14.69683"
|
||||
inkscape:cy="8.8039511"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<path
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="M 11 3 L 11 5.1601562 A 7.5 7.5 0 0 0 8.3671875 6.2460938 L 6.84375 4.7226562 L 4.7226562 6.84375 L 6.2480469 8.3691406 A 7.5 7.5 0 0 0 5.1523438 11 L 3 11 L 3 14 L 5.1601562 14 A 7.5 7.5 0 0 0 6.2460938 16.632812 L 4.7226562 18.15625 L 6.84375 20.277344 L 8.3691406 18.751953 A 7.5 7.5 0 0 0 11 19.847656 L 11 22 L 14 22 L 14 19.839844 A 7.5 7.5 0 0 0 16.632812 18.753906 L 18.15625 20.277344 L 20.277344 18.15625 L 18.751953 16.630859 A 7.5 7.5 0 0 0 19.847656 14 L 22 14 L 22 11 L 19.839844 11 A 7.5 7.5 0 0 0 18.753906 8.3671875 L 20.277344 6.84375 L 18.15625 4.7226562 L 16.630859 6.2480469 A 7.5 7.5 0 0 0 14 5.1523438 L 14 3 L 11 3 z M 12.5 10 A 2.5 2.5 0 0 1 15 12.5 A 2.5 2.5 0 0 1 12.5 15 A 2.5 2.5 0 0 1 10 12.5 A 2.5 2.5 0 0 1 12.5 10 z "
|
||||
transform="translate(0,1027.3622)"
|
||||
id="rect4967" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.0 KiB |
86
public/novnc/app/images/tab.svg
Normal file
@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="tab.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="16"
|
||||
inkscape:cx="11.67335"
|
||||
inkscape:cy="17.881696"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<path
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 3,1031.3622 0,8 2,0 0,-4 0,-4 -2,0 z m 2,4 4,4 0,-3 13,0 0,-2 -13,0 0,-3 -4,4 z"
|
||||
id="rect5194"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path5211"
|
||||
d="m 22,1048.3622 0,-8 -2,0 0,4 0,4 2,0 z m -2,-4 -4,-4 0,3 -13,0 0,2 13,0 0,3 4,-4 z"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
90
public/novnc/app/images/toggleextrakeys.svg
Normal file
@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="extrakeys.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="15.234555"
|
||||
inkscape:cy="9.9710826"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 8,1031.3622 c -2.1987124,0 -4,1.8013 -4,4 l 0,8.9996 c 0,2.1987 1.8012876,4 4,4 l 9,0 c 2.198712,0 4,-1.8013 4,-4 l 0,-8.9996 c 0,-2.1987 -1.801288,-4 -4,-4 z m 0,2 9,0 c 1.125307,0 2,0.8747 2,2 l 0,7.0005 c 0,1.1253 -0.874693,2 -2,2 l -9,0 c -1.1253069,0 -2,-0.8747 -2,-2 l 0,-7.0005 c 0,-1.1253 0.8746931,-2 2,-2 z"
|
||||
id="rect5006"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ssssssssssssssssss" />
|
||||
<g
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="text4167"
|
||||
transform="matrix(0.96021948,0,0,0.96021948,0.18921715,41.80659)">
|
||||
<path
|
||||
d="m 14.292969,1040.6791 -2.939453,0 -0.463868,1.3281 -1.889648,0 2.700195,-7.29 2.241211,0 2.700196,7.29 -1.889649,0 -0.458984,-1.3281 z m -2.470703,-1.3526 1.99707,0 -0.996094,-2.9004 -1.000976,2.9004 z"
|
||||
id="path4172"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
81
public/novnc/app/images/warning.svg
Normal file
@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="warning.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#959595"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="16.457343"
|
||||
inkscape:cy="12.179552"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
showguides="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1027.3622)">
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="M 12.513672 3.0019531 C 11.751609 2.9919531 11.052563 3.4242687 10.710938 4.1054688 L 3.2109375 19.105469 C 2.5461937 20.435369 3.5132277 21.9999 5 22 L 20 22 C 21.486772 21.9999 22.453806 20.435369 21.789062 19.105469 L 14.289062 4.1054688 C 13.951849 3.4330688 13.265888 3.0066531 12.513672 3.0019531 z M 12.478516 6.9804688 A 1.50015 1.50015 0 0 1 14 8.5 L 14 14.5 A 1.50015 1.50015 0 1 1 11 14.5 L 11 8.5 A 1.50015 1.50015 0 0 1 12.478516 6.9804688 z M 12.5 17 A 1.5 1.5 0 0 1 14 18.5 A 1.5 1.5 0 0 1 12.5 20 A 1.5 1.5 0 0 1 11 18.5 A 1.5 1.5 0 0 1 12.5 17 z "
|
||||
transform="translate(0,1027.3622)"
|
||||
id="path4208" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.8 KiB |
85
public/novnc/app/images/windows.svg
Normal file
@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
sodipodi:docname="windows.svg"
|
||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="-293 384 25 23"
|
||||
xml:space="preserve"
|
||||
width="25"
|
||||
height="23"><metadata
|
||||
id="metadata21"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs19" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
id="namedview17"
|
||||
showgrid="false"
|
||||
inkscape:pagecheckerboard="true"
|
||||
inkscape:zoom="9.44"
|
||||
inkscape:cx="-0.84745763"
|
||||
inkscape:cy="12.5"
|
||||
inkscape:window-x="2552"
|
||||
inkscape:window-y="122"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2" />
|
||||
<style
|
||||
type="text/css"
|
||||
id="style2">
|
||||
.st0{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g
|
||||
id="g14"
|
||||
transform="matrix(1.2624869,0,0,1.3601695,73.614445,-144.84322)">
|
||||
<g
|
||||
id="g12">
|
||||
<path
|
||||
class="st0"
|
||||
d="m -277.4,396 c -0.7,0 -1.3,0 -2,0 -0.4,0 -0.5,-0.1 -0.5,-0.5 0,-1 0,-2 0,-3 0,-0.3 0.2,-0.5 0.5,-0.5 1.3,-0.1 2.6,-0.3 3.9,-0.4 0.4,0 0.7,0.1 0.7,0.6 0,1.1 0,2.2 0,3.3 0,0.4 -0.2,0.6 -0.6,0.6 -0.7,-0.1 -1.4,-0.1 -2,-0.1 z"
|
||||
id="path4"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
class="st0"
|
||||
d="m -274.9,399.3 c 0,0.6 0,1.1 0,1.7 0,0.4 -0.1,0.6 -0.6,0.6 -1.4,-0.1 -2.8,-0.3 -4.1,-0.4 -0.3,0 -0.4,-0.3 -0.4,-0.5 0,-1 0,-2 0,-3 0,-0.4 0.2,-0.5 0.6,-0.5 1.3,0 2.6,0 3.9,0 0.5,0 0.6,0.2 0.6,0.6 0,0.4 0,0.9 0,1.5 z"
|
||||
id="path6"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
class="st0"
|
||||
d="m -283.5,396 c -0.6,0 -1.3,0 -1.9,0 -0.4,0 -0.6,-0.1 -0.6,-0.6 0,-0.8 0,-1.5 0,-2.3 0,-0.4 0.2,-0.6 0.6,-0.7 1.3,-0.1 2.7,-0.3 4,-0.4 0.4,0 0.5,0.1 0.5,0.5 0,1 0,1.9 0,2.9 0,0.4 -0.2,0.5 -0.5,0.5 -0.8,0.1 -1.5,0.1 -2.1,0.1 z"
|
||||
id="path8"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
class="st0"
|
||||
d="m -283.5,397 c 0.6,0 1.3,0 1.9,0 0.4,0 0.6,0.1 0.6,0.5 0,1 0,1.9 0,2.9 0,0.4 -0.2,0.5 -0.5,0.5 -1.3,-0.1 -2.7,-0.3 -4,-0.4 -0.4,0 -0.6,-0.2 -0.6,-0.7 0,-0.7 0,-1.5 0,-2.2 0,-0.5 0.2,-0.7 0.7,-0.7 0.6,0.1 1.2,0.1 1.9,0.1 z"
|
||||
id="path10"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#ffffff" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
71
public/novnc/app/locale/cs.json
Normal file
@ -0,0 +1,71 @@
|
||||
{
|
||||
"Connecting...": "Připojení...",
|
||||
"Disconnecting...": "Odpojení...",
|
||||
"Reconnecting...": "Obnova připojení...",
|
||||
"Internal error": "Vnitřní chyba",
|
||||
"Must set host": "Hostitel musí být nastavení",
|
||||
"Connected (encrypted) to ": "Připojení (šifrované) k ",
|
||||
"Connected (unencrypted) to ": "Připojení (nešifrované) k ",
|
||||
"Something went wrong, connection is closed": "Něco se pokazilo, odpojeno",
|
||||
"Failed to connect to server": "Chyba připojení k serveru",
|
||||
"Disconnected": "Odpojeno",
|
||||
"New connection has been rejected with reason: ": "Nové připojení bylo odmítnuto s odůvodněním: ",
|
||||
"New connection has been rejected": "Nové připojení bylo odmítnuto",
|
||||
"Password is required": "Je vyžadováno heslo",
|
||||
"noVNC encountered an error:": "noVNC narazilo na chybu:",
|
||||
"Hide/Show the control bar": "Skrýt/zobrazit ovládací panel",
|
||||
"Move/Drag Viewport": "Přesunout/přetáhnout výřez",
|
||||
"viewport drag": "přesun výřezu",
|
||||
"Active Mouse Button": "Aktivní tlačítka myši",
|
||||
"No mousebutton": "Žádné",
|
||||
"Left mousebutton": "Levé tlačítko myši",
|
||||
"Middle mousebutton": "Prostřední tlačítko myši",
|
||||
"Right mousebutton": "Pravé tlačítko myši",
|
||||
"Keyboard": "Klávesnice",
|
||||
"Show Keyboard": "Zobrazit klávesnici",
|
||||
"Extra keys": "Extra klávesy",
|
||||
"Show Extra Keys": "Zobrazit extra klávesy",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Přepnout Ctrl",
|
||||
"Alt": "Alt",
|
||||
"Toggle Alt": "Přepnout Alt",
|
||||
"Send Tab": "Odeslat tabulátor",
|
||||
"Tab": "Tab",
|
||||
"Esc": "Esc",
|
||||
"Send Escape": "Odeslat Esc",
|
||||
"Ctrl+Alt+Del": "Ctrl+Alt+Del",
|
||||
"Send Ctrl-Alt-Del": "Poslat Ctrl-Alt-Del",
|
||||
"Shutdown/Reboot": "Vypnutí/Restart",
|
||||
"Shutdown/Reboot...": "Vypnutí/Restart...",
|
||||
"Power": "Napájení",
|
||||
"Shutdown": "Vypnout",
|
||||
"Reboot": "Restart",
|
||||
"Reset": "Reset",
|
||||
"Clipboard": "Schránka",
|
||||
"Clear": "Vymazat",
|
||||
"Fullscreen": "Celá obrazovka",
|
||||
"Settings": "Nastavení",
|
||||
"Shared Mode": "Sdílený režim",
|
||||
"View Only": "Pouze prohlížení",
|
||||
"Clip to Window": "Přizpůsobit oknu",
|
||||
"Scaling Mode:": "Přizpůsobení velikosti",
|
||||
"None": "Žádné",
|
||||
"Local Scaling": "Místní",
|
||||
"Remote Resizing": "Vzdálené",
|
||||
"Advanced": "Pokročilé",
|
||||
"Repeater ID:": "ID opakovače",
|
||||
"WebSocket": "WebSocket",
|
||||
"Encrypt": "Šifrování:",
|
||||
"Host:": "Hostitel:",
|
||||
"Port:": "Port:",
|
||||
"Path:": "Cesta",
|
||||
"Automatic Reconnect": "Automatická obnova připojení",
|
||||
"Reconnect Delay (ms):": "Zpoždění připojení (ms)",
|
||||
"Show Dot when No Cursor": "Tečka místo chybějícího kurzoru myši",
|
||||
"Logging:": "Logování:",
|
||||
"Disconnect": "Odpojit",
|
||||
"Connect": "Připojit",
|
||||
"Password:": "Heslo",
|
||||
"Send Password": "Odeslat heslo",
|
||||
"Cancel": "Zrušit"
|
||||
}
|
69
public/novnc/app/locale/de.json
Normal file
@ -0,0 +1,69 @@
|
||||
{
|
||||
"Connecting...": "Verbinden...",
|
||||
"Disconnecting...": "Verbindung trennen...",
|
||||
"Reconnecting...": "Verbindung wiederherstellen...",
|
||||
"Internal error": "Interner Fehler",
|
||||
"Must set host": "Richten Sie den Server ein",
|
||||
"Connected (encrypted) to ": "Verbunden mit (verschlüsselt) ",
|
||||
"Connected (unencrypted) to ": "Verbunden mit (unverschlüsselt) ",
|
||||
"Something went wrong, connection is closed": "Etwas lief schief, Verbindung wurde getrennt",
|
||||
"Disconnected": "Verbindung zum Server getrennt",
|
||||
"New connection has been rejected with reason: ": "Verbindung wurde aus folgendem Grund abgelehnt: ",
|
||||
"New connection has been rejected": "Verbindung wurde abgelehnt",
|
||||
"Password is required": "Passwort ist erforderlich",
|
||||
"noVNC encountered an error:": "Ein Fehler ist aufgetreten:",
|
||||
"Hide/Show the control bar": "Kontrollleiste verstecken/anzeigen",
|
||||
"Move/Drag Viewport": "Ansichtsfenster verschieben/ziehen",
|
||||
"viewport drag": "Ansichtsfenster ziehen",
|
||||
"Active Mouse Button": "Aktive Maustaste",
|
||||
"No mousebutton": "Keine Maustaste",
|
||||
"Left mousebutton": "Linke Maustaste",
|
||||
"Middle mousebutton": "Mittlere Maustaste",
|
||||
"Right mousebutton": "Rechte Maustaste",
|
||||
"Keyboard": "Tastatur",
|
||||
"Show Keyboard": "Tastatur anzeigen",
|
||||
"Extra keys": "Zusatztasten",
|
||||
"Show Extra Keys": "Zusatztasten anzeigen",
|
||||
"Ctrl": "Strg",
|
||||
"Toggle Ctrl": "Strg umschalten",
|
||||
"Alt": "Alt",
|
||||
"Toggle Alt": "Alt umschalten",
|
||||
"Send Tab": "Tab senden",
|
||||
"Tab": "Tab",
|
||||
"Esc": "Esc",
|
||||
"Send Escape": "Escape senden",
|
||||
"Ctrl+Alt+Del": "Strg+Alt+Entf",
|
||||
"Send Ctrl-Alt-Del": "Strg+Alt+Entf senden",
|
||||
"Shutdown/Reboot": "Herunterfahren/Neustarten",
|
||||
"Shutdown/Reboot...": "Herunterfahren/Neustarten...",
|
||||
"Power": "Energie",
|
||||
"Shutdown": "Herunterfahren",
|
||||
"Reboot": "Neustarten",
|
||||
"Reset": "Zurücksetzen",
|
||||
"Clipboard": "Zwischenablage",
|
||||
"Clear": "Löschen",
|
||||
"Fullscreen": "Vollbild",
|
||||
"Settings": "Einstellungen",
|
||||
"Shared Mode": "Geteilter Modus",
|
||||
"View Only": "Nur betrachten",
|
||||
"Clip to Window": "Auf Fenster begrenzen",
|
||||
"Scaling Mode:": "Skalierungsmodus:",
|
||||
"None": "Keiner",
|
||||
"Local Scaling": "Lokales skalieren",
|
||||
"Remote Resizing": "Serverseitiges skalieren",
|
||||
"Advanced": "Erweitert",
|
||||
"Repeater ID:": "Repeater ID:",
|
||||
"WebSocket": "WebSocket",
|
||||
"Encrypt": "Verschlüsselt",
|
||||
"Host:": "Server:",
|
||||
"Port:": "Port:",
|
||||
"Path:": "Pfad:",
|
||||
"Automatic Reconnect": "Automatisch wiederverbinden",
|
||||
"Reconnect Delay (ms):": "Wiederverbindungsverzögerung (ms):",
|
||||
"Logging:": "Protokollierung:",
|
||||
"Disconnect": "Verbindung trennen",
|
||||
"Connect": "Verbinden",
|
||||
"Password:": "Passwort:",
|
||||
"Cancel": "Abbrechen",
|
||||
"Canvas not supported.": "Canvas nicht unterstützt."
|
||||
}
|
69
public/novnc/app/locale/el.json
Normal file
@ -0,0 +1,69 @@
|
||||
{
|
||||
"Connecting...": "Συνδέεται...",
|
||||
"Disconnecting...": "Aποσυνδέεται...",
|
||||
"Reconnecting...": "Επανασυνδέεται...",
|
||||
"Internal error": "Εσωτερικό σφάλμα",
|
||||
"Must set host": "Πρέπει να οριστεί ο διακομιστής",
|
||||
"Connected (encrypted) to ": "Συνδέθηκε (κρυπτογραφημένα) με το ",
|
||||
"Connected (unencrypted) to ": "Συνδέθηκε (μη κρυπτογραφημένα) με το ",
|
||||
"Something went wrong, connection is closed": "Κάτι πήγε στραβά, η σύνδεση διακόπηκε",
|
||||
"Disconnected": "Αποσυνδέθηκε",
|
||||
"New connection has been rejected with reason: ": "Η νέα σύνδεση απορρίφθηκε διότι: ",
|
||||
"New connection has been rejected": "Η νέα σύνδεση απορρίφθηκε ",
|
||||
"Password is required": "Απαιτείται ο κωδικός πρόσβασης",
|
||||
"noVNC encountered an error:": "το noVNC αντιμετώπισε ένα σφάλμα:",
|
||||
"Hide/Show the control bar": "Απόκρυψη/Εμφάνιση γραμμής ελέγχου",
|
||||
"Move/Drag Viewport": "Μετακίνηση/Σύρσιμο Θεατού πεδίου",
|
||||
"viewport drag": "σύρσιμο θεατού πεδίου",
|
||||
"Active Mouse Button": "Ενεργό Πλήκτρο Ποντικιού",
|
||||
"No mousebutton": "Χωρίς Πλήκτρο Ποντικιού",
|
||||
"Left mousebutton": "Αριστερό Πλήκτρο Ποντικιού",
|
||||
"Middle mousebutton": "Μεσαίο Πλήκτρο Ποντικιού",
|
||||
"Right mousebutton": "Δεξί Πλήκτρο Ποντικιού",
|
||||
"Keyboard": "Πληκτρολόγιο",
|
||||
"Show Keyboard": "Εμφάνιση Πληκτρολογίου",
|
||||
"Extra keys": "Επιπλέον πλήκτρα",
|
||||
"Show Extra Keys": "Εμφάνιση Επιπλέον Πλήκτρων",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Εναλλαγή Ctrl",
|
||||
"Alt": "Alt",
|
||||
"Toggle Alt": "Εναλλαγή Alt",
|
||||
"Send Tab": "Αποστολή Tab",
|
||||
"Tab": "Tab",
|
||||
"Esc": "Esc",
|
||||
"Send Escape": "Αποστολή Escape",
|
||||
"Ctrl+Alt+Del": "Ctrl+Alt+Del",
|
||||
"Send Ctrl-Alt-Del": "Αποστολή Ctrl-Alt-Del",
|
||||
"Shutdown/Reboot": "Κλείσιμο/Επανεκκίνηση",
|
||||
"Shutdown/Reboot...": "Κλείσιμο/Επανεκκίνηση...",
|
||||
"Power": "Απενεργοποίηση",
|
||||
"Shutdown": "Κλείσιμο",
|
||||
"Reboot": "Επανεκκίνηση",
|
||||
"Reset": "Επαναφορά",
|
||||
"Clipboard": "Πρόχειρο",
|
||||
"Clear": "Καθάρισμα",
|
||||
"Fullscreen": "Πλήρης Οθόνη",
|
||||
"Settings": "Ρυθμίσεις",
|
||||
"Shared Mode": "Κοινόχρηστη Λειτουργία",
|
||||
"View Only": "Μόνο Θέαση",
|
||||
"Clip to Window": "Αποκοπή στο όριο του Παράθυρου",
|
||||
"Scaling Mode:": "Λειτουργία Κλιμάκωσης:",
|
||||
"None": "Καμία",
|
||||
"Local Scaling": "Τοπική Κλιμάκωση",
|
||||
"Remote Resizing": "Απομακρυσμένη Αλλαγή μεγέθους",
|
||||
"Advanced": "Για προχωρημένους",
|
||||
"Repeater ID:": "Repeater ID:",
|
||||
"WebSocket": "WebSocket",
|
||||
"Encrypt": "Κρυπτογράφηση",
|
||||
"Host:": "Όνομα διακομιστή:",
|
||||
"Port:": "Πόρτα διακομιστή:",
|
||||
"Path:": "Διαδρομή:",
|
||||
"Automatic Reconnect": "Αυτόματη επανασύνδεση",
|
||||
"Reconnect Delay (ms):": "Καθυστέρηση επανασύνδεσης (ms):",
|
||||
"Logging:": "Καταγραφή:",
|
||||
"Disconnect": "Αποσύνδεση",
|
||||
"Connect": "Σύνδεση",
|
||||
"Password:": "Κωδικός Πρόσβασης:",
|
||||
"Cancel": "Ακύρωση",
|
||||
"Canvas not supported.": "Δεν υποστηρίζεται το στοιχείο Canvas"
|
||||
}
|
68
public/novnc/app/locale/es.json
Normal file
@ -0,0 +1,68 @@
|
||||
{
|
||||
"Connecting...": "Conectando...",
|
||||
"Connected (encrypted) to ": "Conectado (con encriptación) a",
|
||||
"Connected (unencrypted) to ": "Conectado (sin encriptación) a",
|
||||
"Disconnecting...": "Desconectando...",
|
||||
"Disconnected": "Desconectado",
|
||||
"Must set host": "Debes configurar el host",
|
||||
"Reconnecting...": "Reconectando...",
|
||||
"Password is required": "Contraseña es obligatoria",
|
||||
"Disconnect timeout": "Tiempo de desconexión agotado",
|
||||
"noVNC encountered an error:": "noVNC ha encontrado un error:",
|
||||
"Hide/Show the control bar": "Ocultar/Mostrar la barra de control",
|
||||
"Move/Drag Viewport": "Mover/Arrastrar la ventana",
|
||||
"viewport drag": "Arrastrar la ventana",
|
||||
"Active Mouse Button": "Botón activo del ratón",
|
||||
"No mousebutton": "Ningún botón del ratón",
|
||||
"Left mousebutton": "Botón izquierdo del ratón",
|
||||
"Middle mousebutton": "Botón central del ratón",
|
||||
"Right mousebutton": "Botón derecho del ratón",
|
||||
"Keyboard": "Teclado",
|
||||
"Show Keyboard": "Mostrar teclado",
|
||||
"Extra keys": "Teclas adicionales",
|
||||
"Show Extra Keys": "Mostrar Teclas Adicionales",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Pulsar/Soltar Ctrl",
|
||||
"Alt": "Alt",
|
||||
"Toggle Alt": "Pulsar/Soltar Alt",
|
||||
"Send Tab": "Enviar Tabulación",
|
||||
"Tab": "Tabulación",
|
||||
"Esc": "Esc",
|
||||
"Send Escape": "Enviar Escape",
|
||||
"Ctrl+Alt+Del": "Ctrl+Alt+Del",
|
||||
"Send Ctrl-Alt-Del": "Enviar Ctrl+Alt+Del",
|
||||
"Shutdown/Reboot": "Apagar/Reiniciar",
|
||||
"Shutdown/Reboot...": "Apagar/Reiniciar...",
|
||||
"Power": "Encender",
|
||||
"Shutdown": "Apagar",
|
||||
"Reboot": "Reiniciar",
|
||||
"Reset": "Restablecer",
|
||||
"Clipboard": "Portapapeles",
|
||||
"Clear": "Vaciar",
|
||||
"Fullscreen": "Pantalla Completa",
|
||||
"Settings": "Configuraciones",
|
||||
"Shared Mode": "Modo Compartido",
|
||||
"View Only": "Solo visualización",
|
||||
"Clip to Window": "Recortar al tamaño de la ventana",
|
||||
"Scaling Mode:": "Modo de escalado:",
|
||||
"None": "Ninguno",
|
||||
"Local Scaling": "Escalado Local",
|
||||
"Local Downscaling": "Reducción de escala local",
|
||||
"Remote Resizing": "Cambio de tamaño remoto",
|
||||
"Advanced": "Avanzado",
|
||||
"Local Cursor": "Cursor Local",
|
||||
"Repeater ID:": "ID del Repetidor",
|
||||
"WebSocket": "WebSocket",
|
||||
"Encrypt": "",
|
||||
"Host:": "Host",
|
||||
"Port:": "Puesto",
|
||||
"Path:": "Ruta",
|
||||
"Automatic Reconnect": "Reconexión automática",
|
||||
"Reconnect Delay (ms):": "Retraso en la reconexión (ms)",
|
||||
"Logging:": "Logging",
|
||||
"Disconnect": "Desconectar",
|
||||
"Connect": "Conectar",
|
||||
"Password:": "Contraseña",
|
||||
"Cancel": "Cancelar",
|
||||
"Canvas not supported.": "Canvas no está soportado"
|
||||
}
|
70
public/novnc/app/locale/ko.json
Normal file
@ -0,0 +1,70 @@
|
||||
{
|
||||
"Connecting...": "연결중...",
|
||||
"Disconnecting...": "연결 해제중...",
|
||||
"Reconnecting...": "재연결중...",
|
||||
"Internal error": "내부 오류",
|
||||
"Must set host": "호스트는 설정되어야 합니다.",
|
||||
"Connected (encrypted) to ": "다음과 (암호화되어) 연결되었습니다:",
|
||||
"Connected (unencrypted) to ": "다음과 (암호화 없이) 연결되었습니다:",
|
||||
"Something went wrong, connection is closed": "무언가 잘못되었습니다, 연결이 닫혔습니다.",
|
||||
"Failed to connect to server": "서버에 연결하지 못했습니다.",
|
||||
"Disconnected": "연결이 해제되었습니다.",
|
||||
"New connection has been rejected with reason: ": "새 연결이 다음 이유로 거부되었습니다:",
|
||||
"New connection has been rejected": "새 연결이 거부되었습니다.",
|
||||
"Password is required": "비밀번호가 필요합니다.",
|
||||
"noVNC encountered an error:": "noVNC에 오류가 발생했습니다:",
|
||||
"Hide/Show the control bar": "컨트롤 바 숨기기/보이기",
|
||||
"Move/Drag Viewport": "움직이기/드래그 뷰포트",
|
||||
"viewport drag": "뷰포트 드래그",
|
||||
"Active Mouse Button": "마우스 버튼 활성화",
|
||||
"No mousebutton": "마우스 버튼 없음",
|
||||
"Left mousebutton": "왼쪽 마우스 버튼",
|
||||
"Middle mousebutton": "중간 마우스 버튼",
|
||||
"Right mousebutton": "오른쪽 마우스 버튼",
|
||||
"Keyboard": "키보드",
|
||||
"Show Keyboard": "키보드 보이기",
|
||||
"Extra keys": "기타 키들",
|
||||
"Show Extra Keys": "기타 키들 보이기",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Ctrl 켜기/끄기",
|
||||
"Alt": "Alt",
|
||||
"Toggle Alt": "Alt 켜기/끄기",
|
||||
"Send Tab": "Tab 보내기",
|
||||
"Tab": "Tab",
|
||||
"Esc": "Esc",
|
||||
"Send Escape": "Esc 보내기",
|
||||
"Ctrl+Alt+Del": "Ctrl+Alt+Del",
|
||||
"Send Ctrl-Alt-Del": "Ctrl+Alt+Del 보내기",
|
||||
"Shutdown/Reboot": "셧다운/리붓",
|
||||
"Shutdown/Reboot...": "셧다운/리붓...",
|
||||
"Power": "전원",
|
||||
"Shutdown": "셧다운",
|
||||
"Reboot": "리붓",
|
||||
"Reset": "리셋",
|
||||
"Clipboard": "클립보드",
|
||||
"Clear": "지우기",
|
||||
"Fullscreen": "전체화면",
|
||||
"Settings": "설정",
|
||||
"Shared Mode": "공유 모드",
|
||||
"View Only": "보기 전용",
|
||||
"Clip to Window": "창에 클립",
|
||||
"Scaling Mode:": "스케일링 모드:",
|
||||
"None": "없음",
|
||||
"Local Scaling": "로컬 스케일링",
|
||||
"Remote Resizing": "원격 크기 조절",
|
||||
"Advanced": "고급",
|
||||
"Repeater ID:": "중계 ID",
|
||||
"WebSocket": "웹소켓",
|
||||
"Encrypt": "암호화",
|
||||
"Host:": "호스트:",
|
||||
"Port:": "포트:",
|
||||
"Path:": "위치:",
|
||||
"Automatic Reconnect": "자동 재연결",
|
||||
"Reconnect Delay (ms):": "재연결 지연 시간 (ms)",
|
||||
"Logging:": "로깅",
|
||||
"Disconnect": "연결 해제",
|
||||
"Connect": "연결",
|
||||
"Password:": "비밀번호:",
|
||||
"Send Password": "비밀번호 전송",
|
||||
"Cancel": "취소"
|
||||
}
|
73
public/novnc/app/locale/nl.json
Normal file
@ -0,0 +1,73 @@
|
||||
{
|
||||
"Connecting...": "Verbinden...",
|
||||
"Disconnecting...": "Verbinding verbreken...",
|
||||
"Reconnecting...": "Opnieuw verbinding maken...",
|
||||
"Internal error": "Interne fout",
|
||||
"Must set host": "Host moeten worden ingesteld",
|
||||
"Connected (encrypted) to ": "Verbonden (versleuteld) met ",
|
||||
"Connected (unencrypted) to ": "Verbonden (onversleuteld) met ",
|
||||
"Something went wrong, connection is closed": "Er iets fout gelopen, verbinding werd verbroken",
|
||||
"Failed to connect to server": "Verbinding maken met server is mislukt",
|
||||
"Disconnected": "Verbinding verbroken",
|
||||
"New connection has been rejected with reason: ": "Nieuwe verbinding is geweigerd omwille van de volgende reden: ",
|
||||
"New connection has been rejected": "Nieuwe verbinding is geweigerd",
|
||||
"Password is required": "Wachtwoord is vereist",
|
||||
"noVNC encountered an error:": "noVNC heeft een fout bemerkt:",
|
||||
"Hide/Show the control bar": "Verberg/Toon de bedieningsbalk",
|
||||
"Move/Drag Viewport": "Verplaats/Versleep Kijkvenster",
|
||||
"viewport drag": "kijkvenster slepen",
|
||||
"Active Mouse Button": "Actieve Muisknop",
|
||||
"No mousebutton": "Geen muisknop",
|
||||
"Left mousebutton": "Linker muisknop",
|
||||
"Middle mousebutton": "Middelste muisknop",
|
||||
"Right mousebutton": "Rechter muisknop",
|
||||
"Keyboard": "Toetsenbord",
|
||||
"Show Keyboard": "Toon Toetsenbord",
|
||||
"Extra keys": "Extra toetsen",
|
||||
"Show Extra Keys": "Toon Extra Toetsen",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Ctrl omschakelen",
|
||||
"Alt": "Alt",
|
||||
"Toggle Alt": "Alt omschakelen",
|
||||
"Toggle Windows": "Windows omschakelen",
|
||||
"Windows": "Windows",
|
||||
"Send Tab": "Tab Sturen",
|
||||
"Tab": "Tab",
|
||||
"Esc": "Esc",
|
||||
"Send Escape": "Escape Sturen",
|
||||
"Ctrl+Alt+Del": "Ctrl-Alt-Del",
|
||||
"Send Ctrl-Alt-Del": "Ctrl-Alt-Del Sturen",
|
||||
"Shutdown/Reboot": "Uitschakelen/Herstarten",
|
||||
"Shutdown/Reboot...": "Uitschakelen/Herstarten...",
|
||||
"Power": "Systeem",
|
||||
"Shutdown": "Uitschakelen",
|
||||
"Reboot": "Herstarten",
|
||||
"Reset": "Resetten",
|
||||
"Clipboard": "Klembord",
|
||||
"Clear": "Wissen",
|
||||
"Fullscreen": "Volledig Scherm",
|
||||
"Settings": "Instellingen",
|
||||
"Shared Mode": "Gedeelde Modus",
|
||||
"View Only": "Alleen Kijken",
|
||||
"Clip to Window": "Randen buiten venster afsnijden",
|
||||
"Scaling Mode:": "Schaalmodus:",
|
||||
"None": "Geen",
|
||||
"Local Scaling": "Lokaal Schalen",
|
||||
"Remote Resizing": "Op Afstand Formaat Wijzigen",
|
||||
"Advanced": "Geavanceerd",
|
||||
"Repeater ID:": "Repeater ID:",
|
||||
"WebSocket": "WebSocket",
|
||||
"Encrypt": "Versleutelen",
|
||||
"Host:": "Host:",
|
||||
"Port:": "Poort:",
|
||||
"Path:": "Pad:",
|
||||
"Automatic Reconnect": "Automatisch Opnieuw Verbinden",
|
||||
"Reconnect Delay (ms):": "Vertraging voor Opnieuw Verbinden (ms):",
|
||||
"Show Dot when No Cursor": "Geef stip weer indien geen cursor",
|
||||
"Logging:": "Logmeldingen:",
|
||||
"Disconnect": "Verbinding verbreken",
|
||||
"Connect": "Verbinden",
|
||||
"Password:": "Wachtwoord:",
|
||||
"Send Password": "Verzend Wachtwoord:",
|
||||
"Cancel": "Annuleren"
|
||||
}
|
69
public/novnc/app/locale/pl.json
Normal file
@ -0,0 +1,69 @@
|
||||
{
|
||||
"Connecting...": "Łączenie...",
|
||||
"Disconnecting...": "Rozłączanie...",
|
||||
"Reconnecting...": "Łączenie...",
|
||||
"Internal error": "Błąd wewnętrzny",
|
||||
"Must set host": "Host i port są wymagane",
|
||||
"Connected (encrypted) to ": "Połączenie (szyfrowane) z ",
|
||||
"Connected (unencrypted) to ": "Połączenie (nieszyfrowane) z ",
|
||||
"Something went wrong, connection is closed": "Coś poszło źle, połączenie zostało zamknięte",
|
||||
"Disconnected": "Rozłączony",
|
||||
"New connection has been rejected with reason: ": "Nowe połączenie zostało odrzucone z powodu: ",
|
||||
"New connection has been rejected": "Nowe połączenie zostało odrzucone",
|
||||
"Password is required": "Hasło jest wymagane",
|
||||
"noVNC encountered an error:": "noVNC napotkało błąd:",
|
||||
"Hide/Show the control bar": "Pokaż/Ukryj pasek ustawień",
|
||||
"Move/Drag Viewport": "Ruszaj/Przeciągaj Viewport",
|
||||
"viewport drag": "przeciągnij viewport",
|
||||
"Active Mouse Button": "Aktywny Przycisk Myszy",
|
||||
"No mousebutton": "Brak przycisku myszy",
|
||||
"Left mousebutton": "Lewy przycisk myszy",
|
||||
"Middle mousebutton": "Środkowy przycisk myszy",
|
||||
"Right mousebutton": "Prawy przycisk myszy",
|
||||
"Keyboard": "Klawiatura",
|
||||
"Show Keyboard": "Pokaż klawiaturę",
|
||||
"Extra keys": "Przyciski dodatkowe",
|
||||
"Show Extra Keys": "Pokaż przyciski dodatkowe",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Przełącz Ctrl",
|
||||
"Alt": "Alt",
|
||||
"Toggle Alt": "Przełącz Alt",
|
||||
"Send Tab": "Wyślij Tab",
|
||||
"Tab": "Tab",
|
||||
"Esc": "Esc",
|
||||
"Send Escape": "Wyślij Escape",
|
||||
"Ctrl+Alt+Del": "Ctrl+Alt+Del",
|
||||
"Send Ctrl-Alt-Del": "Wyślij Ctrl-Alt-Del",
|
||||
"Shutdown/Reboot": "Wyłącz/Uruchom ponownie",
|
||||
"Shutdown/Reboot...": "Wyłącz/Uruchom ponownie...",
|
||||
"Power": "Włączony",
|
||||
"Shutdown": "Wyłącz",
|
||||
"Reboot": "Uruchom ponownie",
|
||||
"Reset": "Resetuj",
|
||||
"Clipboard": "Schowek",
|
||||
"Clear": "Wyczyść",
|
||||
"Fullscreen": "Pełny ekran",
|
||||
"Settings": "Ustawienia",
|
||||
"Shared Mode": "Tryb Współdzielenia",
|
||||
"View Only": "Tylko Podgląd",
|
||||
"Clip to Window": "Przytnij do Okna",
|
||||
"Scaling Mode:": "Tryb Skalowania:",
|
||||
"None": "Brak",
|
||||
"Local Scaling": "Skalowanie lokalne",
|
||||
"Remote Resizing": "Skalowanie zdalne",
|
||||
"Advanced": "Zaawansowane",
|
||||
"Repeater ID:": "ID Repeatera:",
|
||||
"WebSocket": "WebSocket",
|
||||
"Encrypt": "Szyfrowanie",
|
||||
"Host:": "Host:",
|
||||
"Port:": "Port:",
|
||||
"Path:": "Ścieżka:",
|
||||
"Automatic Reconnect": "Automatycznie wznawiaj połączenie",
|
||||
"Reconnect Delay (ms):": "Opóźnienie wznawiania (ms):",
|
||||
"Logging:": "Poziom logowania:",
|
||||
"Disconnect": "Rozłącz",
|
||||
"Connect": "Połącz",
|
||||
"Password:": "Hasło:",
|
||||
"Cancel": "Anuluj",
|
||||
"Canvas not supported.": "Element Canvas nie jest wspierany."
|
||||
}
|
73
public/novnc/app/locale/ru.json
Normal file
@ -0,0 +1,73 @@
|
||||
{
|
||||
"Connecting...": "Подключение...",
|
||||
"Disconnecting...": "Отключение...",
|
||||
"Reconnecting...": "Переподключение...",
|
||||
"Internal error": "Внутренняя ошибка",
|
||||
"Must set host": "Задайте имя сервера или IP",
|
||||
"Connected (encrypted) to ": "Подключено (с шифрованием) к ",
|
||||
"Connected (unencrypted) to ": "Подключено (без шифрования) к ",
|
||||
"Something went wrong, connection is closed": "Что-то пошло не так, подключение разорвано",
|
||||
"Failed to connect to server": "Ошибка подключения к серверу",
|
||||
"Disconnected": "Отключено",
|
||||
"New connection has been rejected with reason: ": "Подключиться не удалось: ",
|
||||
"New connection has been rejected": "Подключиться не удалось",
|
||||
"Password is required": "Требуется пароль",
|
||||
"noVNC encountered an error:": "Ошибка noVNC: ",
|
||||
"Hide/Show the control bar": "Скрыть/Показать контрольную панель",
|
||||
"Move/Drag Viewport": "Переместить окно",
|
||||
"viewport drag": "Переместить окно",
|
||||
"Active Mouse Button": "Активировать кнопки мыши",
|
||||
"No mousebutton": "Отключить кнопки мыши",
|
||||
"Left mousebutton": "Левая кнопка мыши",
|
||||
"Middle mousebutton": "Средняя кнопка мыши",
|
||||
"Right mousebutton": "Правая кнопка мыши",
|
||||
"Keyboard": "Клавиатура",
|
||||
"Show Keyboard": "Показать клавиатуру",
|
||||
"Extra keys": "Доп. кнопки",
|
||||
"Show Extra Keys": "Показать дополнительные кнопки",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Передать нажатие Ctrl",
|
||||
"Alt": "Alt",
|
||||
"Toggle Alt": "Передать нажатие Alt",
|
||||
"Toggle Windows": "Переключение вкладок",
|
||||
"Windows": "Вкладка",
|
||||
"Send Tab": "Передать нажатие Tab",
|
||||
"Tab": "Tab",
|
||||
"Esc": "Esc",
|
||||
"Send Escape": "Передать нажатие Escape",
|
||||
"Ctrl+Alt+Del": "Ctrl+Alt+Del",
|
||||
"Send Ctrl-Alt-Del": "Передать нажатие Ctrl-Alt-Del",
|
||||
"Shutdown/Reboot": "Выключить/Перезагрузить",
|
||||
"Shutdown/Reboot...": "Выключить/Перезагрузить...",
|
||||
"Power": "Питание",
|
||||
"Shutdown": "Выключить",
|
||||
"Reboot": "Перезагрузить",
|
||||
"Reset": "Сброс",
|
||||
"Clipboard": "Буфер обмена",
|
||||
"Clear": "Очистить",
|
||||
"Fullscreen": "Во весь экран",
|
||||
"Settings": "Настройки",
|
||||
"Shared Mode": "Общий режим",
|
||||
"View Only": "Просмотр",
|
||||
"Clip to Window": "В окно",
|
||||
"Scaling Mode:": "Масштаб:",
|
||||
"None": "Нет",
|
||||
"Local Scaling": "Локльный масштаб",
|
||||
"Remote Resizing": "Удаленный масштаб",
|
||||
"Advanced": "Дополнительно",
|
||||
"Repeater ID:": "Идентификатор ID:",
|
||||
"WebSocket": "WebSocket",
|
||||
"Encrypt": "Шифрование",
|
||||
"Host:": "Сервер:",
|
||||
"Port:": "Порт:",
|
||||
"Path:": "Путь:",
|
||||
"Automatic Reconnect": "Автоматическое переподключение",
|
||||
"Reconnect Delay (ms):": "Задержка переподключения (мс):",
|
||||
"Show Dot when No Cursor": "Показать точку вместо курсора",
|
||||
"Logging:": "Лог:",
|
||||
"Disconnect": "Отключение",
|
||||
"Connect": "Подключение",
|
||||
"Password:": "Пароль:",
|
||||
"Send Password": "Пароль: ",
|
||||
"Cancel": "Выход"
|
||||
}
|
73
public/novnc/app/locale/sv.json
Normal file
@ -0,0 +1,73 @@
|
||||
{
|
||||
"Connecting...": "Ansluter...",
|
||||
"Disconnecting...": "Kopplar ner...",
|
||||
"Reconnecting...": "Återansluter...",
|
||||
"Internal error": "Internt fel",
|
||||
"Must set host": "Du måste specifiera en värd",
|
||||
"Connected (encrypted) to ": "Ansluten (krypterat) till ",
|
||||
"Connected (unencrypted) to ": "Ansluten (okrypterat) till ",
|
||||
"Something went wrong, connection is closed": "Något gick fel, anslutningen avslutades",
|
||||
"Failed to connect to server": "Misslyckades att ansluta till servern",
|
||||
"Disconnected": "Frånkopplad",
|
||||
"New connection has been rejected with reason: ": "Ny anslutning har blivit nekad med följande skäl: ",
|
||||
"New connection has been rejected": "Ny anslutning har blivit nekad",
|
||||
"Password is required": "Lösenord krävs",
|
||||
"noVNC encountered an error:": "noVNC stötte på ett problem:",
|
||||
"Hide/Show the control bar": "Göm/Visa kontrollbaren",
|
||||
"Move/Drag Viewport": "Flytta/Dra Vyn",
|
||||
"viewport drag": "dra vy",
|
||||
"Active Mouse Button": "Aktiv musknapp",
|
||||
"No mousebutton": "Ingen musknapp",
|
||||
"Left mousebutton": "Vänster musknapp",
|
||||
"Middle mousebutton": "Mitten-musknapp",
|
||||
"Right mousebutton": "Höger musknapp",
|
||||
"Keyboard": "Tangentbord",
|
||||
"Show Keyboard": "Visa Tangentbord",
|
||||
"Extra keys": "Extraknappar",
|
||||
"Show Extra Keys": "Visa Extraknappar",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Växla Ctrl",
|
||||
"Alt": "Alt",
|
||||
"Toggle Alt": "Växla Alt",
|
||||
"Toggle Windows": "Växla Windows",
|
||||
"Windows": "Windows",
|
||||
"Send Tab": "Skicka Tab",
|
||||
"Tab": "Tab",
|
||||
"Esc": "Esc",
|
||||
"Send Escape": "Skicka Escape",
|
||||
"Ctrl+Alt+Del": "Ctrl+Alt+Del",
|
||||
"Send Ctrl-Alt-Del": "Skicka Ctrl-Alt-Del",
|
||||
"Shutdown/Reboot": "Stäng av/Boota om",
|
||||
"Shutdown/Reboot...": "Stäng av/Boota om...",
|
||||
"Power": "Ström",
|
||||
"Shutdown": "Stäng av",
|
||||
"Reboot": "Boota om",
|
||||
"Reset": "Återställ",
|
||||
"Clipboard": "Urklipp",
|
||||
"Clear": "Rensa",
|
||||
"Fullscreen": "Fullskärm",
|
||||
"Settings": "Inställningar",
|
||||
"Shared Mode": "Delat Läge",
|
||||
"View Only": "Endast Visning",
|
||||
"Clip to Window": "Begränsa till Fönster",
|
||||
"Scaling Mode:": "Skalningsläge:",
|
||||
"None": "Ingen",
|
||||
"Local Scaling": "Lokal Skalning",
|
||||
"Remote Resizing": "Ändra Storlek",
|
||||
"Advanced": "Avancerat",
|
||||
"Repeater ID:": "Repeater-ID:",
|
||||
"WebSocket": "WebSocket",
|
||||
"Encrypt": "Kryptera",
|
||||
"Host:": "Värd:",
|
||||
"Port:": "Port:",
|
||||
"Path:": "Sökväg:",
|
||||
"Automatic Reconnect": "Automatisk Återanslutning",
|
||||
"Reconnect Delay (ms):": "Fördröjning (ms):",
|
||||
"Show Dot when No Cursor": "Visa prick när ingen muspekare finns",
|
||||
"Logging:": "Loggning:",
|
||||
"Disconnect": "Koppla från",
|
||||
"Connect": "Anslut",
|
||||
"Password:": "Lösenord:",
|
||||
"Send Password": "Skicka lösenord",
|
||||
"Cancel": "Avbryt"
|
||||
}
|
69
public/novnc/app/locale/tr.json
Normal file
@ -0,0 +1,69 @@
|
||||
{
|
||||
"Connecting...": "Bağlanıyor...",
|
||||
"Disconnecting...": "Bağlantı kesiliyor...",
|
||||
"Reconnecting...": "Yeniden bağlantı kuruluyor...",
|
||||
"Internal error": "İç hata",
|
||||
"Must set host": "Sunucuyu kur",
|
||||
"Connected (encrypted) to ": "Bağlı (şifrelenmiş)",
|
||||
"Connected (unencrypted) to ": "Bağlandı (şifrelenmemiş)",
|
||||
"Something went wrong, connection is closed": "Bir şeyler ters gitti, bağlantı kesildi",
|
||||
"Disconnected": "Bağlantı kesildi",
|
||||
"New connection has been rejected with reason: ": "Bağlantı aşağıdaki nedenlerden dolayı reddedildi: ",
|
||||
"New connection has been rejected": "Bağlantı reddedildi",
|
||||
"Password is required": "Şifre gerekli",
|
||||
"noVNC encountered an error:": "Bir hata oluştu:",
|
||||
"Hide/Show the control bar": "Denetim masasını Gizle/Göster",
|
||||
"Move/Drag Viewport": "Görünümü Taşı/Sürükle",
|
||||
"viewport drag": "Görüntü penceresini sürükle",
|
||||
"Active Mouse Button": "Aktif Fare Düğmesi",
|
||||
"No mousebutton": "Fare düğmesi yok",
|
||||
"Left mousebutton": "Farenin sol düğmesi",
|
||||
"Middle mousebutton": "Farenin orta düğmesi",
|
||||
"Right mousebutton": "Farenin sağ düğmesi",
|
||||
"Keyboard": "Klavye",
|
||||
"Show Keyboard": "Klavye Düzenini Göster",
|
||||
"Extra keys": "Ekstra tuşlar",
|
||||
"Show Extra Keys": "Ekstra tuşları göster",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Ctrl Değiştir ",
|
||||
"Alt": "Alt",
|
||||
"Toggle Alt": "Alt Değiştir",
|
||||
"Send Tab": "Sekme Gönder",
|
||||
"Tab": "Sekme",
|
||||
"Esc": "Esc",
|
||||
"Send Escape": "Boşluk Gönder",
|
||||
"Ctrl+Alt+Del": "Ctrl + Alt + Del",
|
||||
"Send Ctrl-Alt-Del": "Ctrl-Alt-Del Gönder",
|
||||
"Shutdown/Reboot": "Kapat/Yeniden Başlat",
|
||||
"Shutdown/Reboot...": "Kapat/Yeniden Başlat...",
|
||||
"Power": "Güç",
|
||||
"Shutdown": "Kapat",
|
||||
"Reboot": "Yeniden Başlat",
|
||||
"Reset": "Sıfırla",
|
||||
"Clipboard": "Pano",
|
||||
"Clear": "Temizle",
|
||||
"Fullscreen": "Tam Ekran",
|
||||
"Settings": "Ayarlar",
|
||||
"Shared Mode": "Paylaşım Modu",
|
||||
"View Only": "Sadece Görüntüle",
|
||||
"Clip to Window": "Pencereye Tıkla",
|
||||
"Scaling Mode:": "Ölçekleme Modu:",
|
||||
"None": "Bilinmeyen",
|
||||
"Local Scaling": "Yerel Ölçeklendirme",
|
||||
"Remote Resizing": "Uzaktan Yeniden Boyutlandırma",
|
||||
"Advanced": "Gelişmiş",
|
||||
"Repeater ID:": "Tekralayıcı ID:",
|
||||
"WebSocket": "WebSocket",
|
||||
"Encrypt": "Şifrele",
|
||||
"Host:": "Ana makine:",
|
||||
"Port:": "Port:",
|
||||
"Path:": "Yol:",
|
||||
"Automatic Reconnect": "Otomatik Yeniden Bağlan",
|
||||
"Reconnect Delay (ms):": "Yeniden Bağlanma Süreci (ms):",
|
||||
"Logging:": "Giriş yapılıyor:",
|
||||
"Disconnect": "Bağlantıyı Kes",
|
||||
"Connect": "Bağlan",
|
||||
"Password:": "Parola:",
|
||||
"Cancel": "Vazgeç",
|
||||
"Canvas not supported.": "Tuval desteklenmiyor."
|
||||
}
|
69
public/novnc/app/locale/zh_CN.json
Normal file
@ -0,0 +1,69 @@
|
||||
{
|
||||
"Connecting...": "链接中...",
|
||||
"Disconnecting...": "正在中断连接...",
|
||||
"Reconnecting...": "重新链接中...",
|
||||
"Internal error": "内部错误",
|
||||
"Must set host": "请提供主机名",
|
||||
"Connected (encrypted) to ": "已加密链接到",
|
||||
"Connected (unencrypted) to ": "未加密链接到",
|
||||
"Something went wrong, connection is closed": "发生错误,链接已关闭",
|
||||
"Failed to connect to server": "无法链接到服务器",
|
||||
"Disconnected": "链接已中断",
|
||||
"New connection has been rejected with reason: ": "链接被拒绝,原因:",
|
||||
"New connection has been rejected": "链接被拒绝",
|
||||
"Password is required": "请提供密码",
|
||||
"noVNC encountered an error:": "noVNC 遇到一个错误:",
|
||||
"Hide/Show the control bar": "显示/隐藏控制列",
|
||||
"Move/Drag Viewport": "拖放显示范围",
|
||||
"viewport drag": "显示范围拖放",
|
||||
"Active Mouse Button": "启动鼠标按鍵",
|
||||
"No mousebutton": "禁用鼠标按鍵",
|
||||
"Left mousebutton": "鼠标左鍵",
|
||||
"Middle mousebutton": "鼠标中鍵",
|
||||
"Right mousebutton": "鼠标右鍵",
|
||||
"Keyboard": "键盘",
|
||||
"Show Keyboard": "显示键盘",
|
||||
"Extra keys": "额外按键",
|
||||
"Show Extra Keys": "显示额外按键",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "切换 Ctrl",
|
||||
"Alt": "Alt",
|
||||
"Toggle Alt": "切换 Alt",
|
||||
"Send Tab": "发送 Tab 键",
|
||||
"Tab": "Tab",
|
||||
"Esc": "Esc",
|
||||
"Send Escape": "发送 Escape 键",
|
||||
"Ctrl+Alt+Del": "Ctrl-Alt-Del",
|
||||
"Send Ctrl-Alt-Del": "发送 Ctrl-Alt-Del 键",
|
||||
"Shutdown/Reboot": "关机/重新启动",
|
||||
"Shutdown/Reboot...": "关机/重新启动...",
|
||||
"Power": "电源",
|
||||
"Shutdown": "关机",
|
||||
"Reboot": "重新启动",
|
||||
"Reset": "重置",
|
||||
"Clipboard": "剪贴板",
|
||||
"Clear": "清除",
|
||||
"Fullscreen": "全屏幕",
|
||||
"Settings": "设置",
|
||||
"Shared Mode": "分享模式",
|
||||
"View Only": "仅检视",
|
||||
"Clip to Window": "限制/裁切窗口大小",
|
||||
"Scaling Mode:": "缩放模式:",
|
||||
"None": "无",
|
||||
"Local Scaling": "本地缩放",
|
||||
"Remote Resizing": "远程调整大小",
|
||||
"Advanced": "高级",
|
||||
"Repeater ID:": "中继站 ID",
|
||||
"WebSocket": "WebSocket",
|
||||
"Encrypt": "加密",
|
||||
"Host:": "主机:",
|
||||
"Port:": "端口:",
|
||||
"Path:": "路径:",
|
||||
"Automatic Reconnect": "自动重新链接",
|
||||
"Reconnect Delay (ms):": "重新链接间隔 (ms):",
|
||||
"Logging:": "日志级别:",
|
||||
"Disconnect": "终端链接",
|
||||
"Connect": "链接",
|
||||
"Password:": "密码:",
|
||||
"Cancel": "取消"
|
||||
}
|
69
public/novnc/app/locale/zh_TW.json
Normal file
@ -0,0 +1,69 @@
|
||||
{
|
||||
"Connecting...": "連線中...",
|
||||
"Disconnecting...": "正在中斷連線...",
|
||||
"Reconnecting...": "重新連線中...",
|
||||
"Internal error": "內部錯誤",
|
||||
"Must set host": "請提供主機資訊",
|
||||
"Connected (encrypted) to ": "已加密連線到",
|
||||
"Connected (unencrypted) to ": "未加密連線到",
|
||||
"Something went wrong, connection is closed": "發生錯誤,連線已關閉",
|
||||
"Failed to connect to server": "無法連線到伺服器",
|
||||
"Disconnected": "連線已中斷",
|
||||
"New connection has been rejected with reason: ": "連線被拒絕,原因:",
|
||||
"New connection has been rejected": "連線被拒絕",
|
||||
"Password is required": "請提供密碼",
|
||||
"noVNC encountered an error:": "noVNC 遇到一個錯誤:",
|
||||
"Hide/Show the control bar": "顯示/隱藏控制列",
|
||||
"Move/Drag Viewport": "拖放顯示範圍",
|
||||
"viewport drag": "顯示範圍拖放",
|
||||
"Active Mouse Button": "啟用滑鼠按鍵",
|
||||
"No mousebutton": "無滑鼠按鍵",
|
||||
"Left mousebutton": "滑鼠左鍵",
|
||||
"Middle mousebutton": "滑鼠中鍵",
|
||||
"Right mousebutton": "滑鼠右鍵",
|
||||
"Keyboard": "鍵盤",
|
||||
"Show Keyboard": "顯示鍵盤",
|
||||
"Extra keys": "額外按鍵",
|
||||
"Show Extra Keys": "顯示額外按鍵",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "切換 Ctrl",
|
||||
"Alt": "Alt",
|
||||
"Toggle Alt": "切換 Alt",
|
||||
"Send Tab": "送出 Tab 鍵",
|
||||
"Tab": "Tab",
|
||||
"Esc": "Esc",
|
||||
"Send Escape": "送出 Escape 鍵",
|
||||
"Ctrl+Alt+Del": "Ctrl-Alt-Del",
|
||||
"Send Ctrl-Alt-Del": "送出 Ctrl-Alt-Del 快捷鍵",
|
||||
"Shutdown/Reboot": "關機/重新啟動",
|
||||
"Shutdown/Reboot...": "關機/重新啟動...",
|
||||
"Power": "電源",
|
||||
"Shutdown": "關機",
|
||||
"Reboot": "重新啟動",
|
||||
"Reset": "重設",
|
||||
"Clipboard": "剪貼簿",
|
||||
"Clear": "清除",
|
||||
"Fullscreen": "全螢幕",
|
||||
"Settings": "設定",
|
||||
"Shared Mode": "分享模式",
|
||||
"View Only": "僅檢視",
|
||||
"Clip to Window": "限制/裁切視窗大小",
|
||||
"Scaling Mode:": "縮放模式:",
|
||||
"None": "無",
|
||||
"Local Scaling": "本機縮放",
|
||||
"Remote Resizing": "遠端調整大小",
|
||||
"Advanced": "進階",
|
||||
"Repeater ID:": "中繼站 ID",
|
||||
"WebSocket": "WebSocket",
|
||||
"Encrypt": "加密",
|
||||
"Host:": "主機:",
|
||||
"Port:": "連接埠:",
|
||||
"Path:": "路徑:",
|
||||
"Automatic Reconnect": "自動重新連線",
|
||||
"Reconnect Delay (ms):": "重新連線間隔 (ms):",
|
||||
"Logging:": "日誌級別:",
|
||||
"Disconnect": "中斷連線",
|
||||
"Connect": "連線",
|
||||
"Password:": "密碼:",
|
||||
"Cancel": "取消"
|
||||
}
|
172
public/novnc/app/localization.js
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Localization Utilities
|
||||
*/
|
||||
|
||||
export class Localizer {
|
||||
constructor() {
|
||||
// Currently configured language
|
||||
this.language = 'en';
|
||||
|
||||
// Current dictionary of translations
|
||||
this.dictionary = undefined;
|
||||
}
|
||||
|
||||
// Configure suitable language based on user preferences
|
||||
setup(supportedLanguages) {
|
||||
this.language = 'en'; // Default: US English
|
||||
|
||||
/*
|
||||
* Navigator.languages only available in Chrome (32+) and FireFox (32+)
|
||||
* Fall back to navigator.language for other browsers
|
||||
*/
|
||||
let userLanguages;
|
||||
if (typeof window.navigator.languages == 'object') {
|
||||
userLanguages = window.navigator.languages;
|
||||
} else {
|
||||
userLanguages = [navigator.language || navigator.userLanguage];
|
||||
}
|
||||
|
||||
for (let i = 0;i < userLanguages.length;i++) {
|
||||
const userLang = userLanguages[i]
|
||||
.toLowerCase()
|
||||
.replace("_", "-")
|
||||
.split("-");
|
||||
|
||||
// Built-in default?
|
||||
if ((userLang[0] === 'en') &&
|
||||
((userLang[1] === undefined) || (userLang[1] === 'us'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// First pass: perfect match
|
||||
for (let j = 0; j < supportedLanguages.length; j++) {
|
||||
const supLang = supportedLanguages[j]
|
||||
.toLowerCase()
|
||||
.replace("_", "-")
|
||||
.split("-");
|
||||
|
||||
if (userLang[0] !== supLang[0]) {
|
||||
continue;
|
||||
}
|
||||
if (userLang[1] !== supLang[1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.language = supportedLanguages[j];
|
||||
return;
|
||||
}
|
||||
|
||||
// Second pass: fallback
|
||||
for (let j = 0;j < supportedLanguages.length;j++) {
|
||||
const supLang = supportedLanguages[j]
|
||||
.toLowerCase()
|
||||
.replace("_", "-")
|
||||
.split("-");
|
||||
|
||||
if (userLang[0] !== supLang[0]) {
|
||||
continue;
|
||||
}
|
||||
if (supLang[1] !== undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.language = supportedLanguages[j];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve localised text
|
||||
get(id) {
|
||||
if (typeof this.dictionary !== 'undefined' && this.dictionary[id]) {
|
||||
return this.dictionary[id];
|
||||
} else {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
// Traverses the DOM and translates relevant fields
|
||||
// See https://html.spec.whatwg.org/multipage/dom.html#attr-translate
|
||||
translateDOM() {
|
||||
const self = this;
|
||||
|
||||
function process(elem, enabled) {
|
||||
function isAnyOf(searchElement, items) {
|
||||
return items.indexOf(searchElement) !== -1;
|
||||
}
|
||||
|
||||
function translateAttribute(elem, attr) {
|
||||
const str = self.get(elem.getAttribute(attr));
|
||||
elem.setAttribute(attr, str);
|
||||
}
|
||||
|
||||
function translateTextNode(node) {
|
||||
const str = self.get(node.data.trim());
|
||||
node.data = str;
|
||||
}
|
||||
|
||||
if (elem.hasAttribute("translate")) {
|
||||
if (isAnyOf(elem.getAttribute("translate"), ["", "yes"])) {
|
||||
enabled = true;
|
||||
} else if (isAnyOf(elem.getAttribute("translate"), ["no"])) {
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
if (elem.hasAttribute("abbr") &&
|
||||
elem.tagName === "TH") {
|
||||
translateAttribute(elem, "abbr");
|
||||
}
|
||||
if (elem.hasAttribute("alt") &&
|
||||
isAnyOf(elem.tagName, ["AREA", "IMG", "INPUT"])) {
|
||||
translateAttribute(elem, "alt");
|
||||
}
|
||||
if (elem.hasAttribute("download") &&
|
||||
isAnyOf(elem.tagName, ["A", "AREA"])) {
|
||||
translateAttribute(elem, "download");
|
||||
}
|
||||
if (elem.hasAttribute("label") &&
|
||||
isAnyOf(elem.tagName, ["MENUITEM", "MENU", "OPTGROUP",
|
||||
"OPTION", "TRACK"])) {
|
||||
translateAttribute(elem, "label");
|
||||
}
|
||||
// FIXME: Should update "lang"
|
||||
if (elem.hasAttribute("placeholder") &&
|
||||
isAnyOf(elem.tagName, ["INPUT", "TEXTAREA"])) {
|
||||
translateAttribute(elem, "placeholder");
|
||||
}
|
||||
if (elem.hasAttribute("title")) {
|
||||
translateAttribute(elem, "title");
|
||||
}
|
||||
if (elem.hasAttribute("value") &&
|
||||
elem.tagName === "INPUT" &&
|
||||
isAnyOf(elem.getAttribute("type"), ["reset", "button", "submit"])) {
|
||||
translateAttribute(elem, "value");
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < elem.childNodes.length; i++) {
|
||||
const node = elem.childNodes[i];
|
||||
if (node.nodeType === node.ELEMENT_NODE) {
|
||||
process(node, enabled);
|
||||
} else if (node.nodeType === node.TEXT_NODE && enabled) {
|
||||
translateTextNode(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
process(document.body, true);
|
||||
}
|
||||
}
|
||||
|
||||
export const l10n = new Localizer();
|
||||
export default l10n.get.bind(l10n);
|
4
public/novnc/app/sounds/CREDITS
Normal file
@ -0,0 +1,4 @@
|
||||
bell
|
||||
Copyright: Dr. Richard Boulanger et al
|
||||
URL: http://www.archive.org/details/Berklee44v12
|
||||
License: CC-BY Attribution 3.0 Unported
|
BIN
public/novnc/app/sounds/bell.mp3
Normal file
BIN
public/novnc/app/sounds/bell.oga
Normal file
BIN
public/novnc/app/styles/Orbitron700.ttf
Normal file
BIN
public/novnc/app/styles/Orbitron700.woff
Normal file
900
public/novnc/app/styles/base.css
Normal file
@ -0,0 +1,900 @@
|
||||
/*
|
||||
* noVNC base CSS
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
|
||||
* This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Z index layers:
|
||||
*
|
||||
* 0: Main screen
|
||||
* 10: Control bar
|
||||
* 50: Transition blocker
|
||||
* 60: Connection popups
|
||||
* 100: Status bar
|
||||
* ...
|
||||
* 1000: Javascript crash
|
||||
* ...
|
||||
* 10000: Max (used for polyfills)
|
||||
*/
|
||||
|
||||
body {
|
||||
margin:0;
|
||||
padding:0;
|
||||
font-family: Helvetica;
|
||||
/*Background image with light grey curve.*/
|
||||
background-color:#494949;
|
||||
background-repeat:no-repeat;
|
||||
background-position:right bottom;
|
||||
height:100%;
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
html {
|
||||
height:100%;
|
||||
}
|
||||
|
||||
.noVNC_only_touch.noVNC_hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.noVNC_disabled {
|
||||
color: rgb(128, 128, 128);
|
||||
}
|
||||
|
||||
/* ----------------------------------------
|
||||
* Spinner
|
||||
* ----------------------------------------
|
||||
*/
|
||||
|
||||
.noVNC_spinner {
|
||||
position: relative;
|
||||
}
|
||||
.noVNC_spinner, .noVNC_spinner::before, .noVNC_spinner::after {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
box-shadow: -60px 10px 0 rgba(255, 255, 255, 0);
|
||||
animation: noVNC_spinner 1.0s linear infinite;
|
||||
}
|
||||
.noVNC_spinner::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
animation-delay: -0.1s;
|
||||
}
|
||||
.noVNC_spinner::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
@keyframes noVNC_spinner {
|
||||
0% { box-shadow: -60px 10px 0 rgba(255, 255, 255, 0); width: 20px; }
|
||||
25% { box-shadow: 20px 10px 0 rgba(255, 255, 255, 1); width: 10px; }
|
||||
50% { box-shadow: 60px 10px 0 rgba(255, 255, 255, 0); width: 10px; }
|
||||
}
|
||||
|
||||
/* ----------------------------------------
|
||||
* Input Elements
|
||||
* ----------------------------------------
|
||||
*/
|
||||
|
||||
input[type=input], input[type=password], input[type=number],
|
||||
input:not([type]), textarea {
|
||||
/* Disable default rendering */
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
background: none;
|
||||
|
||||
margin: 2px;
|
||||
padding: 2px;
|
||||
border: 1px solid rgb(192, 192, 192);
|
||||
border-radius: 5px;
|
||||
color: black;
|
||||
background: linear-gradient(to top, rgb(255, 255, 255) 80%, rgb(240, 240, 240));
|
||||
}
|
||||
|
||||
input[type=button], input[type=submit], select {
|
||||
/* Disable default rendering */
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
background: none;
|
||||
|
||||
margin: 2px;
|
||||
padding: 2px;
|
||||
border: 1px solid rgb(192, 192, 192);
|
||||
border-bottom-width: 2px;
|
||||
border-radius: 5px;
|
||||
color: black;
|
||||
background: linear-gradient(to top, rgb(255, 255, 255), rgb(240, 240, 240));
|
||||
|
||||
/* This avoids it jumping around when :active */
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
input[type=button], input[type=submit] {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
option {
|
||||
color: black;
|
||||
background: white;
|
||||
}
|
||||
|
||||
input[type=input]:focus, input[type=password]:focus,
|
||||
input:not([type]):focus, input[type=button]:focus,
|
||||
input[type=submit]:focus,
|
||||
textarea:focus, select:focus {
|
||||
box-shadow: 0px 0px 3px rgba(74, 144, 217, 0.5);
|
||||
border-color: rgb(74, 144, 217);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input[type=button]::-moz-focus-inner,
|
||||
input[type=submit]::-moz-focus-inner {
|
||||
border: none;
|
||||
}
|
||||
|
||||
input[type=input]:disabled, input[type=password]:disabled,
|
||||
input:not([type]):disabled, input[type=button]:disabled,
|
||||
input[type=submit]:disabled, input[type=number]:disabled,
|
||||
textarea:disabled, select:disabled {
|
||||
color: rgb(128, 128, 128);
|
||||
background: rgb(240, 240, 240);
|
||||
}
|
||||
|
||||
input[type=button]:active, input[type=submit]:active,
|
||||
select:active {
|
||||
border-bottom-width: 1px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
:root:not(.noVNC_touch) input[type=button]:hover:not(:disabled),
|
||||
:root:not(.noVNC_touch) input[type=submit]:hover:not(:disabled),
|
||||
:root:not(.noVNC_touch) select:hover:not(:disabled) {
|
||||
background: linear-gradient(to top, rgb(255, 255, 255), rgb(250, 250, 250));
|
||||
}
|
||||
|
||||
/* ----------------------------------------
|
||||
* WebKit centering hacks
|
||||
* ----------------------------------------
|
||||
*/
|
||||
|
||||
.noVNC_center {
|
||||
/*
|
||||
* This is a workaround because webkit misrenders transforms and
|
||||
* uses non-integer coordinates, resulting in blurry content.
|
||||
* Ideally we'd use "top: 50%; transform: translateY(-50%);" on
|
||||
* the objects instead.
|
||||
*/
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
.noVNC_center > * {
|
||||
pointer-events: auto;
|
||||
}
|
||||
.noVNC_vcenter {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
.noVNC_vcenter > * {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* ----------------------------------------
|
||||
* Layering
|
||||
* ----------------------------------------
|
||||
*/
|
||||
|
||||
.noVNC_connect_layer {
|
||||
z-index: 60;
|
||||
}
|
||||
|
||||
/* ----------------------------------------
|
||||
* Fallback error
|
||||
* ----------------------------------------
|
||||
*/
|
||||
|
||||
#noVNC_fallback_error {
|
||||
z-index: 1000;
|
||||
visibility: hidden;
|
||||
}
|
||||
#noVNC_fallback_error.noVNC_open {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#noVNC_fallback_error > div {
|
||||
max-width: 90%;
|
||||
padding: 15px;
|
||||
|
||||
transition: 0.5s ease-in-out;
|
||||
|
||||
transform: translateY(-50px);
|
||||
opacity: 0;
|
||||
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
|
||||
border-radius: 10px;
|
||||
box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5);
|
||||
background: rgba(200,55,55,0.8);
|
||||
}
|
||||
#noVNC_fallback_error.noVNC_open > div {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#noVNC_fallback_errormsg {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#noVNC_fallback_errormsg .noVNC_message {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
font-family: monospace;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
#noVNC_fallback_error .noVNC_location {
|
||||
font-style: italic;
|
||||
font-size: 0.8em;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
#noVNC_fallback_error .noVNC_stack {
|
||||
max-height: 50vh;
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
font-size: 0.8em;
|
||||
text-align: left;
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
border: 1px solid rgba(0, 0, 0, 0.5);
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* ----------------------------------------
|
||||
* Control Bar
|
||||
* ----------------------------------------
|
||||
*/
|
||||
|
||||
#noVNC_control_bar_anchor {
|
||||
/* The anchor is needed to get z-stacking to work */
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
|
||||
transition: 0.5s ease-in-out;
|
||||
|
||||
/* Edge misrenders animations wihthout this */
|
||||
transform: translateX(0);
|
||||
}
|
||||
:root.noVNC_connected #noVNC_control_bar_anchor.noVNC_idle {
|
||||
opacity: 0.8;
|
||||
}
|
||||
#noVNC_control_bar_anchor.noVNC_right {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
#noVNC_control_bar {
|
||||
position: relative;
|
||||
left: -100%;
|
||||
|
||||
transition: 0.5s ease-in-out;
|
||||
|
||||
background-color: rgb(110, 132, 163);
|
||||
border-radius: 0 10px 10px 0;
|
||||
|
||||
}
|
||||
#noVNC_control_bar.noVNC_open {
|
||||
box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5);
|
||||
left: 0;
|
||||
}
|
||||
#noVNC_control_bar::before {
|
||||
/* This extra element is to get a proper shadow */
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
height: 100%;
|
||||
width: 30px;
|
||||
left: -30px;
|
||||
transition: box-shadow 0.5s ease-in-out;
|
||||
}
|
||||
#noVNC_control_bar.noVNC_open::before {
|
||||
box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.noVNC_right #noVNC_control_bar {
|
||||
left: 100%;
|
||||
border-radius: 10px 0 0 10px;
|
||||
}
|
||||
.noVNC_right #noVNC_control_bar.noVNC_open {
|
||||
left: 0;
|
||||
}
|
||||
.noVNC_right #noVNC_control_bar::before {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#noVNC_control_bar_handle {
|
||||
position: absolute;
|
||||
left: -15px;
|
||||
top: 0;
|
||||
transform: translateY(35px);
|
||||
width: calc(100% + 30px);
|
||||
height: 50px;
|
||||
z-index: -1;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
background-color: rgb(83, 99, 122);
|
||||
background-image: url("../images/handle_bg.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right;
|
||||
box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
#noVNC_control_bar_handle:after {
|
||||
content: "";
|
||||
transition: transform 0.5s ease-in-out;
|
||||
background: url("../images/handle.svg");
|
||||
position: absolute;
|
||||
top: 22px; /* (50px-6px)/2 */
|
||||
right: 5px;
|
||||
width: 5px;
|
||||
height: 6px;
|
||||
}
|
||||
#noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after {
|
||||
transform: translateX(1px) rotate(180deg);
|
||||
}
|
||||
:root:not(.noVNC_connected) #noVNC_control_bar_handle {
|
||||
display: none;
|
||||
}
|
||||
.noVNC_right #noVNC_control_bar_handle {
|
||||
background-position: left;
|
||||
}
|
||||
.noVNC_right #noVNC_control_bar_handle:after {
|
||||
left: 5px;
|
||||
right: 0;
|
||||
transform: translateX(1px) rotate(180deg);
|
||||
}
|
||||
.noVNC_right #noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after {
|
||||
transform: none;
|
||||
}
|
||||
#noVNC_control_bar_handle div {
|
||||
position: absolute;
|
||||
right: -35px;
|
||||
top: 0;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
:root:not(.noVNC_touch) #noVNC_control_bar_handle div {
|
||||
display: none;
|
||||
}
|
||||
.noVNC_right #noVNC_control_bar_handle div {
|
||||
left: -35px;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
#noVNC_control_bar .noVNC_scroll {
|
||||
max-height: 100vh; /* Chrome is buggy with 100% */
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding: 0 10px 0 5px;
|
||||
}
|
||||
.noVNC_right #noVNC_control_bar .noVNC_scroll {
|
||||
padding: 0 5px 0 10px;
|
||||
}
|
||||
|
||||
/* Control bar hint */
|
||||
#noVNC_control_bar_hint {
|
||||
position: fixed;
|
||||
left: calc(100vw - 50px);
|
||||
right: auto;
|
||||
top: 50%;
|
||||
transform: translateY(-50%) scale(0);
|
||||
width: 100px;
|
||||
height: 50%;
|
||||
max-height: 600px;
|
||||
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: 0.2s ease-in-out;
|
||||
background: transparent;
|
||||
box-shadow: 0 0 10px black, inset 0 0 10px 10px rgba(110, 132, 163, 0.8);
|
||||
border-radius: 10px;
|
||||
transition-delay: 0s;
|
||||
}
|
||||
#noVNC_control_bar_anchor.noVNC_right #noVNC_control_bar_hint{
|
||||
left: auto;
|
||||
right: calc(100vw - 50px);
|
||||
}
|
||||
#noVNC_control_bar_hint.noVNC_active {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transition-delay: 0.2s;
|
||||
transform: translateY(-50%) scale(1);
|
||||
}
|
||||
|
||||
/* General button style */
|
||||
.noVNC_button {
|
||||
display: block;
|
||||
padding: 4px 4px;
|
||||
margin: 10px 0;
|
||||
vertical-align: middle;
|
||||
border:1px solid rgba(255, 255, 255, 0.2);
|
||||
border-radius: 6px;
|
||||
}
|
||||
.noVNC_button.noVNC_selected {
|
||||
border-color: rgba(0, 0, 0, 0.8);
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.noVNC_button:disabled {
|
||||
opacity: 0.4;
|
||||
}
|
||||
.noVNC_button:focus {
|
||||
outline: none;
|
||||
}
|
||||
.noVNC_button:active {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
/* Android browsers don't properly update hover state if touch events
|
||||
* are intercepted, but focus should be safe to display */
|
||||
:root:not(.noVNC_touch) .noVNC_button.noVNC_selected:hover,
|
||||
.noVNC_button.noVNC_selected:focus {
|
||||
border-color: rgba(0, 0, 0, 0.4);
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
:root:not(.noVNC_touch) .noVNC_button:hover,
|
||||
.noVNC_button:focus {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
.noVNC_button.noVNC_hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Panels */
|
||||
.noVNC_panel {
|
||||
transform: translateX(25px);
|
||||
|
||||
transition: 0.5s ease-in-out;
|
||||
|
||||
max-height: 100vh; /* Chrome is buggy with 100% */
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
|
||||
padding: 15px;
|
||||
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
color: #000;
|
||||
border: 2px solid #E0E0E0;
|
||||
box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.noVNC_panel.noVNC_open {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transform: translateX(75px);
|
||||
}
|
||||
.noVNC_right .noVNC_vcenter {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
.noVNC_right .noVNC_panel {
|
||||
transform: translateX(-25px);
|
||||
}
|
||||
.noVNC_right .noVNC_panel.noVNC_open {
|
||||
transform: translateX(-75px);
|
||||
}
|
||||
|
||||
.noVNC_panel hr {
|
||||
border: none;
|
||||
border-top: 1px solid rgb(192, 192, 192);
|
||||
}
|
||||
|
||||
.noVNC_panel label {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.noVNC_panel .noVNC_heading {
|
||||
background-color: rgb(110, 132, 163);
|
||||
border-radius: 5px;
|
||||
padding: 5px;
|
||||
/* Compensate for padding in image */
|
||||
padding-right: 8px;
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
margin-bottom: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.noVNC_panel .noVNC_heading img {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.noVNC_submit {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* Expanders */
|
||||
.noVNC_expander {
|
||||
cursor: pointer;
|
||||
}
|
||||
.noVNC_expander::before {
|
||||
content: url("../images/expander.svg");
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
transition: 0.2s ease-in-out;
|
||||
}
|
||||
.noVNC_expander.noVNC_open::before {
|
||||
transform: rotateZ(90deg);
|
||||
}
|
||||
.noVNC_expander ~ * {
|
||||
margin: 5px;
|
||||
margin-left: 10px;
|
||||
padding: 5px;
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
border-radius: 5px;
|
||||
}
|
||||
.noVNC_expander:not(.noVNC_open) ~ * {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Control bar content */
|
||||
|
||||
#noVNC_control_bar .noVNC_logo {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
:root:not(.noVNC_connected) #noVNC_view_drag_button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* noVNC Touch Device only buttons */
|
||||
:root:not(.noVNC_connected) #noVNC_mobile_buttons {
|
||||
display: none;
|
||||
}
|
||||
:root:not(.noVNC_touch) #noVNC_mobile_buttons {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Extra manual keys */
|
||||
:root:not(.noVNC_connected) #noVNC_extra_keys {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#noVNC_modifiers {
|
||||
background-color: rgb(92, 92, 92);
|
||||
border: none;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
/* Shutdown/Reboot */
|
||||
:root:not(.noVNC_connected) #noVNC_power_button {
|
||||
display: none;
|
||||
}
|
||||
#noVNC_power {
|
||||
}
|
||||
#noVNC_power_buttons {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#noVNC_power input[type=button] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Clipboard */
|
||||
:root:not(.noVNC_connected) #noVNC_clipboard_button {
|
||||
display: none;
|
||||
}
|
||||
#noVNC_clipboard {
|
||||
/* Full screen, minus padding and left and right margins */
|
||||
max-width: calc(100vw - 2*15px - 75px - 25px);
|
||||
}
|
||||
#noVNC_clipboard_text {
|
||||
width: 500px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* Settings */
|
||||
#noVNC_settings {
|
||||
}
|
||||
#noVNC_settings ul {
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
#noVNC_setting_port {
|
||||
width: 80px;
|
||||
}
|
||||
#noVNC_setting_path {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
/* Connection Controls */
|
||||
:root:not(.noVNC_connected) #noVNC_disconnect_button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ----------------------------------------
|
||||
* Status Dialog
|
||||
* ----------------------------------------
|
||||
*/
|
||||
|
||||
#noVNC_status {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 100;
|
||||
transform: translateY(-100%);
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
transition: 0.5s ease-in-out;
|
||||
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
|
||||
padding: 5px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
|
||||
line-height: 25px;
|
||||
word-wrap: break-word;
|
||||
color: #fff;
|
||||
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
#noVNC_status.noVNC_open {
|
||||
transform: translateY(0);
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#noVNC_status::before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#noVNC_status.noVNC_status_normal {
|
||||
background: rgba(128,128,128,0.9);
|
||||
}
|
||||
#noVNC_status.noVNC_status_normal::before {
|
||||
content: url("../images/info.svg") " ";
|
||||
}
|
||||
#noVNC_status.noVNC_status_error {
|
||||
background: rgba(200,55,55,0.9);
|
||||
}
|
||||
#noVNC_status.noVNC_status_error::before {
|
||||
content: url("../images/error.svg") " ";
|
||||
}
|
||||
#noVNC_status.noVNC_status_warn {
|
||||
background: rgba(180,180,30,0.9);
|
||||
}
|
||||
#noVNC_status.noVNC_status_warn::before {
|
||||
content: url("../images/warning.svg") " ";
|
||||
}
|
||||
|
||||
/* ----------------------------------------
|
||||
* Connect Dialog
|
||||
* ----------------------------------------
|
||||
*/
|
||||
|
||||
#noVNC_connect_dlg {
|
||||
transition: 0.5s ease-in-out;
|
||||
|
||||
transform: scale(0, 0);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
#noVNC_connect_dlg.noVNC_open {
|
||||
transform: scale(1, 1);
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
#noVNC_connect_dlg .noVNC_logo {
|
||||
transition: 0.5s ease-in-out;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
font-size: 80px;
|
||||
text-align: center;
|
||||
|
||||
border-radius: 5px;
|
||||
}
|
||||
@media (max-width: 440px) {
|
||||
#noVNC_connect_dlg {
|
||||
max-width: calc(100vw - 100px);
|
||||
}
|
||||
#noVNC_connect_dlg .noVNC_logo {
|
||||
font-size: calc(25vw - 30px);
|
||||
}
|
||||
}
|
||||
#noVNC_connect_button {
|
||||
cursor: pointer;
|
||||
|
||||
padding: 10px;
|
||||
|
||||
color: white;
|
||||
background-color: rgb(110, 132, 163);
|
||||
border-radius: 12px;
|
||||
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
|
||||
box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
#noVNC_connect_button div {
|
||||
margin: 2px;
|
||||
padding: 5px 30px;
|
||||
border: 1px solid rgb(83, 99, 122);
|
||||
border-bottom-width: 2px;
|
||||
border-radius: 5px;
|
||||
background: linear-gradient(to top, rgb(110, 132, 163), rgb(99, 119, 147));
|
||||
|
||||
/* This avoids it jumping around when :active */
|
||||
vertical-align: middle;
|
||||
}
|
||||
#noVNC_connect_button div:active {
|
||||
border-bottom-width: 1px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
:root:not(.noVNC_touch) #noVNC_connect_button div:hover {
|
||||
background: linear-gradient(to top, rgb(110, 132, 163), rgb(105, 125, 155));
|
||||
}
|
||||
|
||||
#noVNC_connect_button img {
|
||||
vertical-align: bottom;
|
||||
height: 1.3em;
|
||||
}
|
||||
|
||||
/* ----------------------------------------
|
||||
* Password Dialog
|
||||
* ----------------------------------------
|
||||
*/
|
||||
|
||||
#noVNC_password_dlg {
|
||||
position: relative;
|
||||
|
||||
transform: translateY(-50px);
|
||||
}
|
||||
#noVNC_password_dlg.noVNC_open {
|
||||
transform: translateY(0);
|
||||
}
|
||||
#noVNC_password_dlg ul {
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
/* ----------------------------------------
|
||||
* Main Area
|
||||
* ----------------------------------------
|
||||
*/
|
||||
|
||||
/* Transition screen */
|
||||
#noVNC_transition {
|
||||
display: none;
|
||||
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
|
||||
color: white;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 50;
|
||||
|
||||
/*display: flex;*/
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
:root.noVNC_loading #noVNC_transition,
|
||||
:root.noVNC_connecting #noVNC_transition,
|
||||
:root.noVNC_disconnecting #noVNC_transition,
|
||||
:root.noVNC_reconnecting #noVNC_transition {
|
||||
display: flex;
|
||||
}
|
||||
:root:not(.noVNC_reconnecting) #noVNC_cancel_reconnect_button {
|
||||
display: none;
|
||||
}
|
||||
#noVNC_transition_text {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
/* Main container */
|
||||
#noVNC_container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #313131;
|
||||
border-bottom-right-radius: 800px 600px;
|
||||
/*border-top-left-radius: 800px 600px;*/
|
||||
}
|
||||
|
||||
#noVNC_keyboardinput {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
background-color: #fff;
|
||||
color: #fff;
|
||||
border: 0;
|
||||
position: absolute;
|
||||
left: -40px;
|
||||
z-index: -1;
|
||||
ime-mode: disabled;
|
||||
}
|
||||
|
||||
/*Default noVNC logo.*/
|
||||
/* From: http://fonts.googleapis.com/css?family=Orbitron:700 */
|
||||
@font-face {
|
||||
font-family: 'Orbitron';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('?'), url('Orbitron700.woff') format('woff'),
|
||||
url('Orbitron700.ttf') format('truetype');
|
||||
}
|
||||
|
||||
.noVNC_logo {
|
||||
color:yellow;
|
||||
font-family: 'Orbitron', 'OrbitronTTF', sans-serif;
|
||||
line-height:90%;
|
||||
text-shadow: 0.1em 0.1em 0 black;
|
||||
}
|
||||
.noVNC_logo span{
|
||||
color:green;
|
||||
}
|
||||
|
||||
#noVNC_bell {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ----------------------------------------
|
||||
* Media sizing
|
||||
* ----------------------------------------
|
||||
*/
|
||||
|
||||
@media screen and (max-width: 640px){
|
||||
#noVNC_logo {
|
||||
font-size: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 321px) and (max-width: 480px) {
|
||||
#noVNC_logo {
|
||||
font-size: 110px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 320px) {
|
||||
#noVNC_logo {
|
||||
font-size: 90px;
|
||||
}
|
||||
}
|
1649
public/novnc/app/ui.js
Normal file
239
public/novnc/app/webutil.js
Normal file
@ -0,0 +1,239 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*/
|
||||
|
||||
import { init_logging as main_init_logging } from '../core/util/logging.js';
|
||||
|
||||
// init log level reading the logging HTTP param
|
||||
export function init_logging(level) {
|
||||
"use strict";
|
||||
if (typeof level !== "undefined") {
|
||||
main_init_logging(level);
|
||||
} else {
|
||||
const param = document.location.href.match(/logging=([A-Za-z0-9._-]*)/);
|
||||
main_init_logging(param || undefined);
|
||||
}
|
||||
}
|
||||
|
||||
// Read a query string variable
|
||||
export function getQueryVar(name, defVal) {
|
||||
"use strict";
|
||||
const re = new RegExp('.*[?&]' + name + '=([^&#]*)'),
|
||||
match = document.location.href.match(re);
|
||||
if (typeof defVal === 'undefined') { defVal = null; }
|
||||
|
||||
if (match) {
|
||||
return decodeURIComponent(match[1]);
|
||||
}
|
||||
|
||||
return defVal;
|
||||
}
|
||||
|
||||
// Read a hash fragment variable
|
||||
export function getHashVar(name, defVal) {
|
||||
"use strict";
|
||||
const re = new RegExp('.*[&#]' + name + '=([^&]*)'),
|
||||
match = document.location.hash.match(re);
|
||||
if (typeof defVal === 'undefined') { defVal = null; }
|
||||
|
||||
if (match) {
|
||||
return decodeURIComponent(match[1]);
|
||||
}
|
||||
|
||||
return defVal;
|
||||
}
|
||||
|
||||
// Read a variable from the fragment or the query string
|
||||
// Fragment takes precedence
|
||||
export function getConfigVar(name, defVal) {
|
||||
"use strict";
|
||||
const val = getHashVar(name);
|
||||
|
||||
if (val === null) {
|
||||
return getQueryVar(name, defVal);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html
|
||||
*/
|
||||
|
||||
// No days means only for this browser session
|
||||
export function createCookie(name, value, days) {
|
||||
"use strict";
|
||||
let date, expires;
|
||||
if (days) {
|
||||
date = new Date();
|
||||
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||
expires = "; expires=" + date.toGMTString();
|
||||
} else {
|
||||
expires = "";
|
||||
}
|
||||
|
||||
let secure;
|
||||
if (document.location.protocol === "https:") {
|
||||
secure = "; secure";
|
||||
} else {
|
||||
secure = "";
|
||||
}
|
||||
document.cookie = name + "=" + value + expires + "; path=/" + secure;
|
||||
}
|
||||
|
||||
export function readCookie(name, defaultValue) {
|
||||
"use strict";
|
||||
const nameEQ = name + "=";
|
||||
const ca = document.cookie.split(';');
|
||||
|
||||
for (let i = 0; i < ca.length; i += 1) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) === ' ') {
|
||||
c = c.substring(1, c.length);
|
||||
}
|
||||
if (c.indexOf(nameEQ) === 0) {
|
||||
return c.substring(nameEQ.length, c.length);
|
||||
}
|
||||
}
|
||||
|
||||
return (typeof defaultValue !== 'undefined') ? defaultValue : null;
|
||||
}
|
||||
|
||||
export function eraseCookie(name) {
|
||||
"use strict";
|
||||
createCookie(name, "", -1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setting handling.
|
||||
*/
|
||||
|
||||
let settings = {};
|
||||
|
||||
export function initSettings() {
|
||||
if (!window.chrome || !window.chrome.storage) {
|
||||
settings = {};
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return new Promise(resolve => window.chrome.storage.sync.get(resolve))
|
||||
.then((cfg) => { settings = cfg; });
|
||||
}
|
||||
|
||||
// Update the settings cache, but do not write to permanent storage
|
||||
export function setSetting(name, value) {
|
||||
settings[name] = value;
|
||||
}
|
||||
|
||||
// No days means only for this browser session
|
||||
export function writeSetting(name, value) {
|
||||
"use strict";
|
||||
if (settings[name] === value) return;
|
||||
settings[name] = value;
|
||||
if (window.chrome && window.chrome.storage) {
|
||||
window.chrome.storage.sync.set(settings);
|
||||
} else {
|
||||
localStorage.setItem(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
export function readSetting(name, defaultValue) {
|
||||
"use strict";
|
||||
let value;
|
||||
if ((name in settings) || (window.chrome && window.chrome.storage)) {
|
||||
value = settings[name];
|
||||
} else {
|
||||
value = localStorage.getItem(name);
|
||||
settings[name] = value;
|
||||
}
|
||||
if (typeof value === "undefined") {
|
||||
value = null;
|
||||
}
|
||||
|
||||
if (value === null && typeof defaultValue !== "undefined") {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
export function eraseSetting(name) {
|
||||
"use strict";
|
||||
// Deleting here means that next time the setting is read when using local
|
||||
// storage, it will be pulled from local storage again.
|
||||
// If the setting in local storage is changed (e.g. in another tab)
|
||||
// between this delete and the next read, it could lead to an unexpected
|
||||
// value change.
|
||||
delete settings[name];
|
||||
if (window.chrome && window.chrome.storage) {
|
||||
window.chrome.storage.sync.remove(name);
|
||||
} else {
|
||||
localStorage.removeItem(name);
|
||||
}
|
||||
}
|
||||
|
||||
export function injectParamIfMissing(path, param, value) {
|
||||
// force pretend that we're dealing with a relative path
|
||||
// (assume that we wanted an extra if we pass one in)
|
||||
path = "/" + path;
|
||||
|
||||
const elem = document.createElement('a');
|
||||
elem.href = path;
|
||||
|
||||
const param_eq = encodeURIComponent(param) + "=";
|
||||
let query;
|
||||
if (elem.search) {
|
||||
query = elem.search.slice(1).split('&');
|
||||
} else {
|
||||
query = [];
|
||||
}
|
||||
|
||||
if (!query.some(v => v.startsWith(param_eq))) {
|
||||
query.push(param_eq + encodeURIComponent(value));
|
||||
elem.search = "?" + query.join("&");
|
||||
}
|
||||
|
||||
// some browsers (e.g. IE11) may occasionally omit the leading slash
|
||||
// in the elem.pathname string. Handle that case gracefully.
|
||||
if (elem.pathname.charAt(0) == "/") {
|
||||
return elem.pathname.slice(1) + elem.search + elem.hash;
|
||||
}
|
||||
|
||||
return elem.pathname + elem.search + elem.hash;
|
||||
}
|
||||
|
||||
// sadly, we can't use the Fetch API until we decide to drop
|
||||
// IE11 support or polyfill promises and fetch in IE11.
|
||||
// resolve will receive an object on success, while reject
|
||||
// will receive either an event or an error on failure.
|
||||
export function fetchJSON(path) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// NB: IE11 doesn't support JSON as a responseType
|
||||
const req = new XMLHttpRequest();
|
||||
req.open('GET', path);
|
||||
|
||||
req.onload = () => {
|
||||
if (req.status === 200) {
|
||||
let resObj;
|
||||
try {
|
||||
resObj = JSON.parse(req.responseText);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
resolve(resObj);
|
||||
} else {
|
||||
reject(new Error("XHR got non-200 status while trying to load '" + path + "': " + req.status));
|
||||
}
|
||||
};
|
||||
|
||||
req.onerror = evt => reject(new Error("XHR encountered an error while trying to load '" + path + "': " + evt.message));
|
||||
|
||||
req.ontimeout = evt => reject(new Error("XHR timed out while trying to load '" + path + "'"));
|
||||
|
||||
req.send();
|
||||
});
|
||||
}
|
104
public/novnc/core/base64.js
Normal file
@ -0,0 +1,104 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js
|
||||
|
||||
import * as Log from './util/logging.js';
|
||||
|
||||
export default {
|
||||
/* Convert data (an array of integers) to a Base64 string. */
|
||||
toBase64Table: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
|
||||
base64Pad: '=',
|
||||
|
||||
encode(data) {
|
||||
"use strict";
|
||||
let result = '';
|
||||
const length = data.length;
|
||||
const lengthpad = (length % 3);
|
||||
// Convert every three bytes to 4 ascii characters.
|
||||
|
||||
for (let i = 0; i < (length - 2); i += 3) {
|
||||
result += this.toBase64Table[data[i] >> 2];
|
||||
result += this.toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
|
||||
result += this.toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
|
||||
result += this.toBase64Table[data[i + 2] & 0x3f];
|
||||
}
|
||||
|
||||
// Convert the remaining 1 or 2 bytes, pad out to 4 characters.
|
||||
const j = length - lengthpad;
|
||||
if (lengthpad === 2) {
|
||||
result += this.toBase64Table[data[j] >> 2];
|
||||
result += this.toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)];
|
||||
result += this.toBase64Table[(data[j + 1] & 0x0f) << 2];
|
||||
result += this.toBase64Table[64];
|
||||
} else if (lengthpad === 1) {
|
||||
result += this.toBase64Table[data[j] >> 2];
|
||||
result += this.toBase64Table[(data[j] & 0x03) << 4];
|
||||
result += this.toBase64Table[64];
|
||||
result += this.toBase64Table[64];
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
/* Convert Base64 data to a string */
|
||||
/* eslint-disable comma-spacing */
|
||||
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
|
||||
],
|
||||
/* eslint-enable comma-spacing */
|
||||
|
||||
decode(data, offset = 0) {
|
||||
let data_length = data.indexOf('=') - offset;
|
||||
if (data_length < 0) { data_length = data.length - offset; }
|
||||
|
||||
/* Every four characters is 3 resulting numbers */
|
||||
const result_length = (data_length >> 2) * 3 + Math.floor((data_length % 4) / 1.5);
|
||||
const result = new Array(result_length);
|
||||
|
||||
// Convert one by one.
|
||||
|
||||
let leftbits = 0; // number of bits decoded, but yet to be appended
|
||||
let leftdata = 0; // bits decoded, but yet to be appended
|
||||
for (let idx = 0, i = offset; i < data.length; i++) {
|
||||
const c = this.toBinaryTable[data.charCodeAt(i) & 0x7f];
|
||||
const padding = (data.charAt(i) === this.base64Pad);
|
||||
// Skip illegal characters and whitespace
|
||||
if (c === -1) {
|
||||
Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Collect data into leftdata, update bitcount
|
||||
leftdata = (leftdata << 6) | c;
|
||||
leftbits += 6;
|
||||
|
||||
// If we have 8 or more bits, append 8 bits to the result
|
||||
if (leftbits >= 8) {
|
||||
leftbits -= 8;
|
||||
// Append if not padding.
|
||||
if (!padding) {
|
||||
result[idx++] = (leftdata >> leftbits) & 0xff;
|
||||
}
|
||||
leftdata &= (1 << leftbits) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// If there are any bits left, the base64 string was corrupted
|
||||
if (leftbits) {
|
||||
const err = new Error('Corrupted base64 string');
|
||||
err.name = 'Base64-Error';
|
||||
throw err;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}; /* End of Base64 namespace */
|
24
public/novnc/core/decoders/copyrect.js
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2012 Joel Martin
|
||||
* Copyright (C) 2018 Samuel Mannehed for Cendio AB
|
||||
* Copyright (C) 2018 Pierre Ossman for Cendio AB
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*
|
||||
*/
|
||||
|
||||
export default class CopyRectDecoder {
|
||||
decodeRect(x, y, width, height, sock, display, depth) {
|
||||
if (sock.rQwait("COPYRECT", 4)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let deltaX = sock.rQshift16();
|
||||
let deltaY = sock.rQshift16();
|
||||
display.copyImage(deltaX, deltaY, x, y, width, height);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
139
public/novnc/core/decoders/hextile.js
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2012 Joel Martin
|
||||
* Copyright (C) 2018 Samuel Mannehed for Cendio AB
|
||||
* Copyright (C) 2018 Pierre Ossman for Cendio AB
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*
|
||||
*/
|
||||
|
||||
import * as Log from '../util/logging.js';
|
||||
|
||||
export default class HextileDecoder {
|
||||
constructor() {
|
||||
this._tiles = 0;
|
||||
this._lastsubencoding = 0;
|
||||
}
|
||||
|
||||
decodeRect(x, y, width, height, sock, display, depth) {
|
||||
if (this._tiles === 0) {
|
||||
this._tiles_x = Math.ceil(width / 16);
|
||||
this._tiles_y = Math.ceil(height / 16);
|
||||
this._total_tiles = this._tiles_x * this._tiles_y;
|
||||
this._tiles = this._total_tiles;
|
||||
}
|
||||
|
||||
while (this._tiles > 0) {
|
||||
let bytes = 1;
|
||||
|
||||
if (sock.rQwait("HEXTILE", bytes)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let rQ = sock.rQ;
|
||||
let rQi = sock.rQi;
|
||||
|
||||
let subencoding = rQ[rQi]; // Peek
|
||||
if (subencoding > 30) { // Raw
|
||||
throw new Error("Illegal hextile subencoding (subencoding: " +
|
||||
subencoding + ")");
|
||||
}
|
||||
|
||||
const curr_tile = this._total_tiles - this._tiles;
|
||||
const tile_x = curr_tile % this._tiles_x;
|
||||
const tile_y = Math.floor(curr_tile / this._tiles_x);
|
||||
const tx = x + tile_x * 16;
|
||||
const ty = y + tile_y * 16;
|
||||
const tw = Math.min(16, (x + width) - tx);
|
||||
const th = Math.min(16, (y + height) - ty);
|
||||
|
||||
// Figure out how much we are expecting
|
||||
if (subencoding & 0x01) { // Raw
|
||||
bytes += tw * th * 4;
|
||||
} else {
|
||||
if (subencoding & 0x02) { // Background
|
||||
bytes += 4;
|
||||
}
|
||||
if (subencoding & 0x04) { // Foreground
|
||||
bytes += 4;
|
||||
}
|
||||
if (subencoding & 0x08) { // AnySubrects
|
||||
bytes++; // Since we aren't shifting it off
|
||||
|
||||
if (sock.rQwait("HEXTILE", bytes)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let subrects = rQ[rQi + bytes - 1]; // Peek
|
||||
if (subencoding & 0x10) { // SubrectsColoured
|
||||
bytes += subrects * (4 + 2);
|
||||
} else {
|
||||
bytes += subrects * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sock.rQwait("HEXTILE", bytes)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We know the encoding and have a whole tile
|
||||
rQi++;
|
||||
if (subencoding === 0) {
|
||||
if (this._lastsubencoding & 0x01) {
|
||||
// Weird: ignore blanks are RAW
|
||||
Log.Debug(" Ignoring blank after RAW");
|
||||
} else {
|
||||
display.fillRect(tx, ty, tw, th, this._background);
|
||||
}
|
||||
} else if (subencoding & 0x01) { // Raw
|
||||
display.blitImage(tx, ty, tw, th, rQ, rQi);
|
||||
rQi += bytes - 1;
|
||||
} else {
|
||||
if (subencoding & 0x02) { // Background
|
||||
this._background = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]];
|
||||
rQi += 4;
|
||||
}
|
||||
if (subencoding & 0x04) { // Foreground
|
||||
this._foreground = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]];
|
||||
rQi += 4;
|
||||
}
|
||||
|
||||
display.startTile(tx, ty, tw, th, this._background);
|
||||
if (subencoding & 0x08) { // AnySubrects
|
||||
let subrects = rQ[rQi];
|
||||
rQi++;
|
||||
|
||||
for (let s = 0; s < subrects; s++) {
|
||||
let color;
|
||||
if (subencoding & 0x10) { // SubrectsColoured
|
||||
color = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]];
|
||||
rQi += 4;
|
||||
} else {
|
||||
color = this._foreground;
|
||||
}
|
||||
const xy = rQ[rQi];
|
||||
rQi++;
|
||||
const sx = (xy >> 4);
|
||||
const sy = (xy & 0x0f);
|
||||
|
||||
const wh = rQ[rQi];
|
||||
rQi++;
|
||||
const sw = (wh >> 4) + 1;
|
||||
const sh = (wh & 0x0f) + 1;
|
||||
|
||||
display.subTile(sx, sy, sw, sh, color);
|
||||
}
|
||||
}
|
||||
display.finishTile();
|
||||
}
|
||||
sock.rQi = rQi;
|
||||
this._lastsubencoding = subencoding;
|
||||
this._tiles--;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
58
public/novnc/core/decoders/raw.js
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2012 Joel Martin
|
||||
* Copyright (C) 2018 Samuel Mannehed for Cendio AB
|
||||
* Copyright (C) 2018 Pierre Ossman for Cendio AB
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*
|
||||
*/
|
||||
|
||||
export default class RawDecoder {
|
||||
constructor() {
|
||||
this._lines = 0;
|
||||
}
|
||||
|
||||
decodeRect(x, y, width, height, sock, display, depth) {
|
||||
if (this._lines === 0) {
|
||||
this._lines = height;
|
||||
}
|
||||
|
||||
const pixelSize = depth == 8 ? 1 : 4;
|
||||
const bytesPerLine = width * pixelSize;
|
||||
|
||||
if (sock.rQwait("RAW", bytesPerLine)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const cur_y = y + (height - this._lines);
|
||||
const curr_height = Math.min(this._lines,
|
||||
Math.floor(sock.rQlen / bytesPerLine));
|
||||
let data = sock.rQ;
|
||||
let index = sock.rQi;
|
||||
|
||||
// Convert data if needed
|
||||
if (depth == 8) {
|
||||
const pixels = width * curr_height;
|
||||
const newdata = new Uint8Array(pixels * 4);
|
||||
for (let i = 0; i < pixels; i++) {
|
||||
newdata[i * 4 + 0] = ((data[index + i] >> 0) & 0x3) * 255 / 3;
|
||||
newdata[i * 4 + 1] = ((data[index + i] >> 2) & 0x3) * 255 / 3;
|
||||
newdata[i * 4 + 2] = ((data[index + i] >> 4) & 0x3) * 255 / 3;
|
||||
newdata[i * 4 + 4] = 0;
|
||||
}
|
||||
data = newdata;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
display.blitImage(x, cur_y, width, curr_height, data, index);
|
||||
sock.rQskipBytes(curr_height * bytesPerLine);
|
||||
this._lines -= curr_height;
|
||||
if (this._lines > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
46
public/novnc/core/decoders/rre.js
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2012 Joel Martin
|
||||
* Copyright (C) 2018 Samuel Mannehed for Cendio AB
|
||||
* Copyright (C) 2018 Pierre Ossman for Cendio AB
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*
|
||||
*/
|
||||
|
||||
export default class RREDecoder {
|
||||
constructor() {
|
||||
this._subrects = 0;
|
||||
}
|
||||
|
||||
decodeRect(x, y, width, height, sock, display, depth) {
|
||||
if (this._subrects === 0) {
|
||||
if (sock.rQwait("RRE", 4 + 4)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this._subrects = sock.rQshift32();
|
||||
|
||||
let color = sock.rQshiftBytes(4); // Background
|
||||
display.fillRect(x, y, width, height, color);
|
||||
}
|
||||
|
||||
while (this._subrects > 0) {
|
||||
if (sock.rQwait("RRE", 4 + 8)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let color = sock.rQshiftBytes(4);
|
||||
let sx = sock.rQshift16();
|
||||
let sy = sock.rQshift16();
|
||||
let swidth = sock.rQshift16();
|
||||
let sheight = sock.rQshift16();
|
||||
display.fillRect(x + sx, y + sy, swidth, sheight, color);
|
||||
|
||||
this._subrects--;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
319
public/novnc/core/decoders/tight.js
Normal file
@ -0,0 +1,319 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2012 Joel Martin
|
||||
* (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca)
|
||||
* Copyright (C) 2018 Samuel Mannehed for Cendio AB
|
||||
* Copyright (C) 2018 Pierre Ossman for Cendio AB
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*
|
||||
*/
|
||||
|
||||
import * as Log from '../util/logging.js';
|
||||
import Inflator from "../inflator.js";
|
||||
|
||||
export default class TightDecoder {
|
||||
constructor() {
|
||||
this._ctl = null;
|
||||
this._filter = null;
|
||||
this._numColors = 0;
|
||||
this._palette = new Uint8Array(1024); // 256 * 4 (max palette size * max bytes-per-pixel)
|
||||
this._len = 0;
|
||||
|
||||
this._zlibs = [];
|
||||
for (let i = 0; i < 4; i++) {
|
||||
this._zlibs[i] = new Inflator();
|
||||
}
|
||||
}
|
||||
|
||||
decodeRect(x, y, width, height, sock, display, depth) {
|
||||
if (this._ctl === null) {
|
||||
if (sock.rQwait("TIGHT compression-control", 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this._ctl = sock.rQshift8();
|
||||
|
||||
// Reset streams if the server requests it
|
||||
for (let i = 0; i < 4; i++) {
|
||||
if ((this._ctl >> i) & 1) {
|
||||
this._zlibs[i].reset();
|
||||
Log.Info("Reset zlib stream " + i);
|
||||
}
|
||||
}
|
||||
|
||||
// Figure out filter
|
||||
this._ctl = this._ctl >> 4;
|
||||
}
|
||||
|
||||
let ret;
|
||||
|
||||
if (this._ctl === 0x08) {
|
||||
ret = this._fillRect(x, y, width, height,
|
||||
sock, display, depth);
|
||||
} else if (this._ctl === 0x09) {
|
||||
ret = this._jpegRect(x, y, width, height,
|
||||
sock, display, depth);
|
||||
} else if (this._ctl === 0x0A) {
|
||||
ret = this._pngRect(x, y, width, height,
|
||||
sock, display, depth);
|
||||
} else if ((this._ctl & 0x80) == 0) {
|
||||
ret = this._basicRect(this._ctl, x, y, width, height,
|
||||
sock, display, depth);
|
||||
} else {
|
||||
throw new Error("Illegal tight compression received (ctl: " +
|
||||
this._ctl + ")");
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
this._ctl = null;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
_fillRect(x, y, width, height, sock, display, depth) {
|
||||
if (sock.rQwait("TIGHT", 3)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const rQi = sock.rQi;
|
||||
const rQ = sock.rQ;
|
||||
|
||||
display.fillRect(x, y, width, height,
|
||||
[rQ[rQi + 2], rQ[rQi + 1], rQ[rQi]], false);
|
||||
sock.rQskipBytes(3);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_jpegRect(x, y, width, height, sock, display, depth) {
|
||||
let data = this._readData(sock);
|
||||
if (data === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
display.imageRect(x, y, "image/jpeg", data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_pngRect(x, y, width, height, sock, display, depth) {
|
||||
throw new Error("PNG received in standard Tight rect");
|
||||
}
|
||||
|
||||
_basicRect(ctl, x, y, width, height, sock, display, depth) {
|
||||
if (this._filter === null) {
|
||||
if (ctl & 0x4) {
|
||||
if (sock.rQwait("TIGHT", 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this._filter = sock.rQshift8();
|
||||
} else {
|
||||
// Implicit CopyFilter
|
||||
this._filter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
let streamId = ctl & 0x3;
|
||||
|
||||
let ret;
|
||||
|
||||
switch (this._filter) {
|
||||
case 0: // CopyFilter
|
||||
ret = this._copyFilter(streamId, x, y, width, height,
|
||||
sock, display, depth);
|
||||
break;
|
||||
case 1: // PaletteFilter
|
||||
ret = this._paletteFilter(streamId, x, y, width, height,
|
||||
sock, display, depth);
|
||||
break;
|
||||
case 2: // GradientFilter
|
||||
ret = this._gradientFilter(streamId, x, y, width, height,
|
||||
sock, display, depth);
|
||||
break;
|
||||
default:
|
||||
throw new Error("Illegal tight filter received (ctl: " +
|
||||
this._filter + ")");
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
this._filter = null;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
_copyFilter(streamId, x, y, width, height, sock, display, depth) {
|
||||
const uncompressedSize = width * height * 3;
|
||||
let data;
|
||||
|
||||
if (uncompressedSize < 12) {
|
||||
if (sock.rQwait("TIGHT", uncompressedSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data = sock.rQshiftBytes(uncompressedSize);
|
||||
} else {
|
||||
data = this._readData(sock);
|
||||
if (data === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data = this._zlibs[streamId].inflate(data, true, uncompressedSize);
|
||||
if (data.length != uncompressedSize) {
|
||||
throw new Error("Incomplete zlib block");
|
||||
}
|
||||
}
|
||||
|
||||
display.blitRgbImage(x, y, width, height, data, 0, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_paletteFilter(streamId, x, y, width, height, sock, display, depth) {
|
||||
if (this._numColors === 0) {
|
||||
if (sock.rQwait("TIGHT palette", 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const numColors = sock.rQpeek8() + 1;
|
||||
const paletteSize = numColors * 3;
|
||||
|
||||
if (sock.rQwait("TIGHT palette", 1 + paletteSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this._numColors = numColors;
|
||||
sock.rQskipBytes(1);
|
||||
|
||||
sock.rQshiftTo(this._palette, paletteSize);
|
||||
}
|
||||
|
||||
const bpp = (this._numColors <= 2) ? 1 : 8;
|
||||
const rowSize = Math.floor((width * bpp + 7) / 8);
|
||||
const uncompressedSize = rowSize * height;
|
||||
|
||||
let data;
|
||||
|
||||
if (uncompressedSize < 12) {
|
||||
if (sock.rQwait("TIGHT", uncompressedSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data = sock.rQshiftBytes(uncompressedSize);
|
||||
} else {
|
||||
data = this._readData(sock);
|
||||
if (data === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data = this._zlibs[streamId].inflate(data, true, uncompressedSize);
|
||||
if (data.length != uncompressedSize) {
|
||||
throw new Error("Incomplete zlib block");
|
||||
}
|
||||
}
|
||||
|
||||
// Convert indexed (palette based) image data to RGB
|
||||
if (this._numColors == 2) {
|
||||
this._monoRect(x, y, width, height, data, this._palette, display);
|
||||
} else {
|
||||
this._paletteRect(x, y, width, height, data, this._palette, display);
|
||||
}
|
||||
|
||||
this._numColors = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_monoRect(x, y, width, height, data, palette, display) {
|
||||
// Convert indexed (palette based) image data to RGB
|
||||
// TODO: reduce number of calculations inside loop
|
||||
const dest = this._getScratchBuffer(width * height * 4);
|
||||
const w = Math.floor((width + 7) / 8);
|
||||
const w1 = Math.floor(width / 8);
|
||||
|
||||
for (let y = 0; y < height; y++) {
|
||||
let dp, sp, x;
|
||||
for (x = 0; x < w1; x++) {
|
||||
for (let b = 7; b >= 0; b--) {
|
||||
dp = (y * width + x * 8 + 7 - b) * 4;
|
||||
sp = (data[y * w + x] >> b & 1) * 3;
|
||||
dest[dp] = palette[sp];
|
||||
dest[dp + 1] = palette[sp + 1];
|
||||
dest[dp + 2] = palette[sp + 2];
|
||||
dest[dp + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
for (let b = 7; b >= 8 - width % 8; b--) {
|
||||
dp = (y * width + x * 8 + 7 - b) * 4;
|
||||
sp = (data[y * w + x] >> b & 1) * 3;
|
||||
dest[dp] = palette[sp];
|
||||
dest[dp + 1] = palette[sp + 1];
|
||||
dest[dp + 2] = palette[sp + 2];
|
||||
dest[dp + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
display.blitRgbxImage(x, y, width, height, dest, 0, false);
|
||||
}
|
||||
|
||||
_paletteRect(x, y, width, height, data, palette, display) {
|
||||
// Convert indexed (palette based) image data to RGB
|
||||
const dest = this._getScratchBuffer(width * height * 4);
|
||||
const total = width * height * 4;
|
||||
for (let i = 0, j = 0; i < total; i += 4, j++) {
|
||||
const sp = data[j] * 3;
|
||||
dest[i] = palette[sp];
|
||||
dest[i + 1] = palette[sp + 1];
|
||||
dest[i + 2] = palette[sp + 2];
|
||||
dest[i + 3] = 255;
|
||||
}
|
||||
|
||||
display.blitRgbxImage(x, y, width, height, dest, 0, false);
|
||||
}
|
||||
|
||||
_gradientFilter(streamId, x, y, width, height, sock, display, depth) {
|
||||
throw new Error("Gradient filter not implemented");
|
||||
}
|
||||
|
||||
_readData(sock) {
|
||||
if (this._len === 0) {
|
||||
if (sock.rQwait("TIGHT", 3)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let byte;
|
||||
|
||||
byte = sock.rQshift8();
|
||||
this._len = byte & 0x7f;
|
||||
if (byte & 0x80) {
|
||||
byte = sock.rQshift8();
|
||||
this._len |= (byte & 0x7f) << 7;
|
||||
if (byte & 0x80) {
|
||||
byte = sock.rQshift8();
|
||||
this._len |= byte << 14;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sock.rQwait("TIGHT", this._len)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let data = sock.rQshiftBytes(this._len);
|
||||
this._len = 0;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
_getScratchBuffer(size) {
|
||||
if (!this._scratchBuffer || (this._scratchBuffer.length < size)) {
|
||||
this._scratchBuffer = new Uint8Array(size);
|
||||
}
|
||||
return this._scratchBuffer;
|
||||
}
|
||||
}
|
29
public/novnc/core/decoders/tightpng.js
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2012 Joel Martin
|
||||
* Copyright (C) 2018 Samuel Mannehed for Cendio AB
|
||||
* Copyright (C) 2018 Pierre Ossman for Cendio AB
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*
|
||||
*/
|
||||
|
||||
import TightDecoder from './tight.js';
|
||||
|
||||
export default class TightPNGDecoder extends TightDecoder {
|
||||
_pngRect(x, y, width, height, sock, display, depth) {
|
||||
let data = this._readData(sock);
|
||||
if (data === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
display.imageRect(x, y, "image/png", data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_basicRect(ctl, x, y, width, height, sock, display, depth) {
|
||||
throw new Error("BasicCompression received in TightPNG rect");
|
||||
}
|
||||
}
|
266
public/novnc/core/des.js
Normal file
@ -0,0 +1,266 @@
|
||||
/*
|
||||
* Ported from Flashlight VNC ActionScript implementation:
|
||||
* http://www.wizhelp.com/flashlight-vnc/
|
||||
*
|
||||
* Full attribution follows:
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* This DES class has been extracted from package Acme.Crypto for use in VNC.
|
||||
* The unnecessary odd parity code has been removed.
|
||||
*
|
||||
* These changes are:
|
||||
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
|
||||
* DesCipher - the DES encryption method
|
||||
*
|
||||
* The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is:
|
||||
*
|
||||
* Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software
|
||||
* and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
|
||||
* without fee is hereby granted, provided that this copyright notice is kept
|
||||
* intact.
|
||||
*
|
||||
* WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
|
||||
* OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE
|
||||
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
|
||||
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
* THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
|
||||
* CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
|
||||
* PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
|
||||
* NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
|
||||
* SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
|
||||
* SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
|
||||
* PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP
|
||||
* SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
|
||||
* HIGH RISK ACTIVITIES.
|
||||
*
|
||||
*
|
||||
* The rest is:
|
||||
*
|
||||
* Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Visit the ACME Labs Java page for up-to-date versions of this and other
|
||||
* fine Java utilities: http://www.acme.com/java/
|
||||
*/
|
||||
|
||||
/* eslint-disable comma-spacing */
|
||||
|
||||
// Tables, permutations, S-boxes, etc.
|
||||
const 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 ],
|
||||
totrot = [ 1, 2, 4, 6, 8,10,12,14,15,17,19,21,23,25,27,28];
|
||||
|
||||
const z = 0x0;
|
||||
let a,b,c,d,e,f;
|
||||
a=1<<16; b=1<<24; c=a|b; d=1<<2; e=1<<10; f=d|e;
|
||||
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,
|
||||
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];
|
||||
a=1<<20; b=1<<31; c=a|b; d=1<<5; e=1<<15; f=d|e;
|
||||
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,
|
||||
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];
|
||||
a=1<<17; b=1<<27; c=a|b; d=1<<3; e=1<<9; f=d|e;
|
||||
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,
|
||||
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];
|
||||
a=1<<13; b=1<<23; c=a|b; d=1<<0; e=1<<7; f=d|e;
|
||||
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,
|
||||
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];
|
||||
a=1<<25; b=1<<30; c=a|b; d=1<<8; e=1<<19; f=d|e;
|
||||
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,
|
||||
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];
|
||||
a=1<<22; b=1<<29; c=a|b; d=1<<4; e=1<<14; f=d|e;
|
||||
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,
|
||||
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];
|
||||
a=1<<21; b=1<<26; c=a|b; d=1<<1; e=1<<11; f=d|e;
|
||||
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,
|
||||
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];
|
||||
a=1<<18; b=1<<28; c=a|b; d=1<<6; e=1<<12; f=d|e;
|
||||
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,
|
||||
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];
|
||||
|
||||
/* eslint-enable comma-spacing */
|
||||
|
||||
export default class DES {
|
||||
constructor(password) {
|
||||
this.keys = [];
|
||||
|
||||
// Set the key.
|
||||
const pc1m = [], pcr = [], kn = [];
|
||||
|
||||
for (let j = 0, l = 56; j < 56; ++j, l -= 8) {
|
||||
l += l < -5 ? 65 : l < -3 ? 31 : l < -1 ? 63 : l === 27 ? 35 : 0; // PC1
|
||||
const m = l & 0x7;
|
||||
pc1m[j] = ((password[l >>> 3] & (1<<m)) !== 0) ? 1: 0;
|
||||
}
|
||||
|
||||
for (let i = 0; i < 16; ++i) {
|
||||
const m = i << 1;
|
||||
const n = m + 1;
|
||||
kn[m] = kn[n] = 0;
|
||||
for (let o = 28; o < 59; o += 28) {
|
||||
for (let j = o - 28; j < o; ++j) {
|
||||
const l = j + totrot[i];
|
||||
pcr[j] = l < o ? pc1m[l] : pc1m[l - 28];
|
||||
}
|
||||
}
|
||||
for (let j = 0; j < 24; ++j) {
|
||||
if (pcr[PC2[j]] !== 0) {
|
||||
kn[m] |= 1 << (23 - j);
|
||||
}
|
||||
if (pcr[PC2[j + 24]] !== 0) {
|
||||
kn[n] |= 1 << (23 - j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cookey
|
||||
for (let i = 0, rawi = 0, KnLi = 0; i < 16; ++i) {
|
||||
const raw0 = kn[rawi++];
|
||||
const raw1 = kn[rawi++];
|
||||
this.keys[KnLi] = (raw0 & 0x00fc0000) << 6;
|
||||
this.keys[KnLi] |= (raw0 & 0x00000fc0) << 10;
|
||||
this.keys[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
|
||||
this.keys[KnLi] |= (raw1 & 0x00000fc0) >>> 6;
|
||||
++KnLi;
|
||||
this.keys[KnLi] = (raw0 & 0x0003f000) << 12;
|
||||
this.keys[KnLi] |= (raw0 & 0x0000003f) << 16;
|
||||
this.keys[KnLi] |= (raw1 & 0x0003f000) >>> 4;
|
||||
this.keys[KnLi] |= (raw1 & 0x0000003f);
|
||||
++KnLi;
|
||||
}
|
||||
}
|
||||
|
||||
// Encrypt 8 bytes of text
|
||||
enc8(text) {
|
||||
const b = text.slice();
|
||||
let i = 0, l, r, x; // left, right, accumulator
|
||||
|
||||
// Squash 8 bytes to 2 ints
|
||||
l = b[i++]<<24 | b[i++]<<16 | b[i++]<<8 | b[i++];
|
||||
r = b[i++]<<24 | b[i++]<<16 | b[i++]<<8 | b[i++];
|
||||
|
||||
x = ((l >>> 4) ^ r) & 0x0f0f0f0f;
|
||||
r ^= x;
|
||||
l ^= (x << 4);
|
||||
x = ((l >>> 16) ^ r) & 0x0000ffff;
|
||||
r ^= x;
|
||||
l ^= (x << 16);
|
||||
x = ((r >>> 2) ^ l) & 0x33333333;
|
||||
l ^= x;
|
||||
r ^= (x << 2);
|
||||
x = ((r >>> 8) ^ l) & 0x00ff00ff;
|
||||
l ^= x;
|
||||
r ^= (x << 8);
|
||||
r = (r << 1) | ((r >>> 31) & 1);
|
||||
x = (l ^ r) & 0xaaaaaaaa;
|
||||
l ^= x;
|
||||
r ^= x;
|
||||
l = (l << 1) | ((l >>> 31) & 1);
|
||||
|
||||
for (let i = 0, keysi = 0; i < 8; ++i) {
|
||||
x = (r << 28) | (r >>> 4);
|
||||
x ^= this.keys[keysi++];
|
||||
let fval = SP7[x & 0x3f];
|
||||
fval |= SP5[(x >>> 8) & 0x3f];
|
||||
fval |= SP3[(x >>> 16) & 0x3f];
|
||||
fval |= SP1[(x >>> 24) & 0x3f];
|
||||
x = r ^ this.keys[keysi++];
|
||||
fval |= SP8[x & 0x3f];
|
||||
fval |= SP6[(x >>> 8) & 0x3f];
|
||||
fval |= SP4[(x >>> 16) & 0x3f];
|
||||
fval |= SP2[(x >>> 24) & 0x3f];
|
||||
l ^= fval;
|
||||
x = (l << 28) | (l >>> 4);
|
||||
x ^= this.keys[keysi++];
|
||||
fval = SP7[x & 0x3f];
|
||||
fval |= SP5[(x >>> 8) & 0x3f];
|
||||
fval |= SP3[(x >>> 16) & 0x3f];
|
||||
fval |= SP1[(x >>> 24) & 0x3f];
|
||||
x = l ^ this.keys[keysi++];
|
||||
fval |= SP8[x & 0x0000003f];
|
||||
fval |= SP6[(x >>> 8) & 0x3f];
|
||||
fval |= SP4[(x >>> 16) & 0x3f];
|
||||
fval |= SP2[(x >>> 24) & 0x3f];
|
||||
r ^= fval;
|
||||
}
|
||||
|
||||
r = (r << 31) | (r >>> 1);
|
||||
x = (l ^ r) & 0xaaaaaaaa;
|
||||
l ^= x;
|
||||
r ^= x;
|
||||
l = (l << 31) | (l >>> 1);
|
||||
x = ((l >>> 8) ^ r) & 0x00ff00ff;
|
||||
r ^= x;
|
||||
l ^= (x << 8);
|
||||
x = ((l >>> 2) ^ r) & 0x33333333;
|
||||
r ^= x;
|
||||
l ^= (x << 2);
|
||||
x = ((r >>> 16) ^ l) & 0x0000ffff;
|
||||
l ^= x;
|
||||
r ^= (x << 16);
|
||||
x = ((r >>> 4) ^ l) & 0x0f0f0f0f;
|
||||
l ^= x;
|
||||
r ^= (x << 4);
|
||||
|
||||
// Spread ints to bytes
|
||||
x = [r, l];
|
||||
for (i = 0; i < 8; i++) {
|
||||
b[i] = (x[i>>>2] >>> (8 * (3 - (i % 4)))) % 256;
|
||||
if (b[i] < 0) { b[i] += 256; } // unsigned
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
// Encrypt 16 bytes of text using passwd as key
|
||||
encrypt(t) {
|
||||
return this.enc8(t.slice(0, 8)).concat(this.enc8(t.slice(8, 16)));
|
||||
}
|
||||
}
|
654
public/novnc/core/display.js
Normal file
@ -0,0 +1,654 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*/
|
||||
|
||||
import * as Log from './util/logging.js';
|
||||
import Base64 from "./base64.js";
|
||||
import { supportsImageMetadata } from './util/browser.js';
|
||||
|
||||
export default class Display {
|
||||
constructor(target) {
|
||||
this._drawCtx = null;
|
||||
this._c_forceCanvas = false;
|
||||
|
||||
this._renderQ = []; // queue drawing actions for in-oder rendering
|
||||
this._flushing = false;
|
||||
|
||||
// the full frame buffer (logical canvas) size
|
||||
this._fb_width = 0;
|
||||
this._fb_height = 0;
|
||||
|
||||
this._prevDrawStyle = "";
|
||||
this._tile = null;
|
||||
this._tile16x16 = null;
|
||||
this._tile_x = 0;
|
||||
this._tile_y = 0;
|
||||
|
||||
Log.Debug(">> Display.constructor");
|
||||
|
||||
// The visible canvas
|
||||
this._target = target;
|
||||
|
||||
if (!this._target) {
|
||||
throw new Error("Target must be set");
|
||||
}
|
||||
|
||||
if (typeof this._target === 'string') {
|
||||
throw new Error('target must be a DOM element');
|
||||
}
|
||||
|
||||
if (!this._target.getContext) {
|
||||
throw new Error("no getContext method");
|
||||
}
|
||||
|
||||
this._targetCtx = this._target.getContext('2d');
|
||||
|
||||
// the visible canvas viewport (i.e. what actually gets seen)
|
||||
this._viewportLoc = { 'x': 0, 'y': 0, 'w': this._target.width, 'h': this._target.height };
|
||||
|
||||
// The hidden canvas, where we do the actual rendering
|
||||
this._backbuffer = document.createElement('canvas');
|
||||
this._drawCtx = this._backbuffer.getContext('2d');
|
||||
|
||||
this._damageBounds = { left: 0, top: 0,
|
||||
right: this._backbuffer.width,
|
||||
bottom: this._backbuffer.height };
|
||||
|
||||
Log.Debug("User Agent: " + navigator.userAgent);
|
||||
|
||||
this.clear();
|
||||
|
||||
// Check canvas features
|
||||
if (!('createImageData' in this._drawCtx)) {
|
||||
throw new Error("Canvas does not support createImageData");
|
||||
}
|
||||
|
||||
this._tile16x16 = this._drawCtx.createImageData(16, 16);
|
||||
Log.Debug("<< Display.constructor");
|
||||
|
||||
// ===== PROPERTIES =====
|
||||
|
||||
this._scale = 1.0;
|
||||
this._clipViewport = false;
|
||||
this.logo = null;
|
||||
|
||||
// ===== EVENT HANDLERS =====
|
||||
|
||||
this.onflush = () => {}; // A flush request has finished
|
||||
}
|
||||
|
||||
// ===== PROPERTIES =====
|
||||
|
||||
get scale() { return this._scale; }
|
||||
set scale(scale) {
|
||||
this._rescale(scale);
|
||||
}
|
||||
|
||||
get clipViewport() { return this._clipViewport; }
|
||||
set clipViewport(viewport) {
|
||||
this._clipViewport = viewport;
|
||||
// May need to readjust the viewport dimensions
|
||||
const vp = this._viewportLoc;
|
||||
this.viewportChangeSize(vp.w, vp.h);
|
||||
this.viewportChangePos(0, 0);
|
||||
}
|
||||
|
||||
get width() {
|
||||
return this._fb_width;
|
||||
}
|
||||
|
||||
get height() {
|
||||
return this._fb_height;
|
||||
}
|
||||
|
||||
// ===== PUBLIC METHODS =====
|
||||
|
||||
viewportChangePos(deltaX, deltaY) {
|
||||
const vp = this._viewportLoc;
|
||||
deltaX = Math.floor(deltaX);
|
||||
deltaY = Math.floor(deltaY);
|
||||
|
||||
if (!this._clipViewport) {
|
||||
deltaX = -vp.w; // clamped later of out of bounds
|
||||
deltaY = -vp.h;
|
||||
}
|
||||
|
||||
const vx2 = vp.x + vp.w - 1;
|
||||
const vy2 = vp.y + vp.h - 1;
|
||||
|
||||
// Position change
|
||||
|
||||
if (deltaX < 0 && vp.x + deltaX < 0) {
|
||||
deltaX = -vp.x;
|
||||
}
|
||||
if (vx2 + deltaX >= this._fb_width) {
|
||||
deltaX -= vx2 + deltaX - this._fb_width + 1;
|
||||
}
|
||||
|
||||
if (vp.y + deltaY < 0) {
|
||||
deltaY = -vp.y;
|
||||
}
|
||||
if (vy2 + deltaY >= this._fb_height) {
|
||||
deltaY -= (vy2 + deltaY - this._fb_height + 1);
|
||||
}
|
||||
|
||||
if (deltaX === 0 && deltaY === 0) {
|
||||
return;
|
||||
}
|
||||
Log.Debug("viewportChange deltaX: " + deltaX + ", deltaY: " + deltaY);
|
||||
|
||||
vp.x += deltaX;
|
||||
vp.y += deltaY;
|
||||
|
||||
this._damage(vp.x, vp.y, vp.w, vp.h);
|
||||
|
||||
this.flip();
|
||||
}
|
||||
|
||||
viewportChangeSize(width, height) {
|
||||
|
||||
if (!this._clipViewport ||
|
||||
typeof(width) === "undefined" ||
|
||||
typeof(height) === "undefined") {
|
||||
|
||||
Log.Debug("Setting viewport to full display region");
|
||||
width = this._fb_width;
|
||||
height = this._fb_height;
|
||||
}
|
||||
|
||||
width = Math.floor(width);
|
||||
height = Math.floor(height);
|
||||
|
||||
if (width > this._fb_width) {
|
||||
width = this._fb_width;
|
||||
}
|
||||
if (height > this._fb_height) {
|
||||
height = this._fb_height;
|
||||
}
|
||||
|
||||
const vp = this._viewportLoc;
|
||||
if (vp.w !== width || vp.h !== height) {
|
||||
vp.w = width;
|
||||
vp.h = height;
|
||||
|
||||
const canvas = this._target;
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
|
||||
// The position might need to be updated if we've grown
|
||||
this.viewportChangePos(0, 0);
|
||||
|
||||
this._damage(vp.x, vp.y, vp.w, vp.h);
|
||||
this.flip();
|
||||
|
||||
// Update the visible size of the target canvas
|
||||
this._rescale(this._scale);
|
||||
}
|
||||
}
|
||||
|
||||
absX(x) {
|
||||
if (this._scale === 0) {
|
||||
return 0;
|
||||
}
|
||||
return x / this._scale + this._viewportLoc.x;
|
||||
}
|
||||
|
||||
absY(y) {
|
||||
if (this._scale === 0) {
|
||||
return 0;
|
||||
}
|
||||
return y / this._scale + this._viewportLoc.y;
|
||||
}
|
||||
|
||||
resize(width, height) {
|
||||
this._prevDrawStyle = "";
|
||||
|
||||
this._fb_width = width;
|
||||
this._fb_height = height;
|
||||
|
||||
const canvas = this._backbuffer;
|
||||
if (canvas.width !== width || canvas.height !== height) {
|
||||
|
||||
// We have to save the canvas data since changing the size will clear it
|
||||
let saveImg = null;
|
||||
if (canvas.width > 0 && canvas.height > 0) {
|
||||
saveImg = this._drawCtx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
|
||||
if (canvas.width !== width) {
|
||||
canvas.width = width;
|
||||
}
|
||||
if (canvas.height !== height) {
|
||||
canvas.height = height;
|
||||
}
|
||||
|
||||
if (saveImg) {
|
||||
this._drawCtx.putImageData(saveImg, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Readjust the viewport as it may be incorrectly sized
|
||||
// and positioned
|
||||
const vp = this._viewportLoc;
|
||||
this.viewportChangeSize(vp.w, vp.h);
|
||||
this.viewportChangePos(0, 0);
|
||||
}
|
||||
|
||||
// Track what parts of the visible canvas that need updating
|
||||
_damage(x, y, w, h) {
|
||||
if (x < this._damageBounds.left) {
|
||||
this._damageBounds.left = x;
|
||||
}
|
||||
if (y < this._damageBounds.top) {
|
||||
this._damageBounds.top = y;
|
||||
}
|
||||
if ((x + w) > this._damageBounds.right) {
|
||||
this._damageBounds.right = x + w;
|
||||
}
|
||||
if ((y + h) > this._damageBounds.bottom) {
|
||||
this._damageBounds.bottom = y + h;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the visible canvas with the contents of the
|
||||
// rendering canvas
|
||||
flip(from_queue) {
|
||||
if (this._renderQ.length !== 0 && !from_queue) {
|
||||
this._renderQ_push({
|
||||
'type': 'flip'
|
||||
});
|
||||
} else {
|
||||
let x = this._damageBounds.left;
|
||||
let y = this._damageBounds.top;
|
||||
let w = this._damageBounds.right - x;
|
||||
let h = this._damageBounds.bottom - y;
|
||||
|
||||
let vx = x - this._viewportLoc.x;
|
||||
let vy = y - this._viewportLoc.y;
|
||||
|
||||
if (vx < 0) {
|
||||
w += vx;
|
||||
x -= vx;
|
||||
vx = 0;
|
||||
}
|
||||
if (vy < 0) {
|
||||
h += vy;
|
||||
y -= vy;
|
||||
vy = 0;
|
||||
}
|
||||
|
||||
if ((vx + w) > this._viewportLoc.w) {
|
||||
w = this._viewportLoc.w - vx;
|
||||
}
|
||||
if ((vy + h) > this._viewportLoc.h) {
|
||||
h = this._viewportLoc.h - vy;
|
||||
}
|
||||
|
||||
if ((w > 0) && (h > 0)) {
|
||||
// FIXME: We may need to disable image smoothing here
|
||||
// as well (see copyImage()), but we haven't
|
||||
// noticed any problem yet.
|
||||
this._targetCtx.drawImage(this._backbuffer,
|
||||
x, y, w, h,
|
||||
vx, vy, w, h);
|
||||
}
|
||||
|
||||
this._damageBounds.left = this._damageBounds.top = 65535;
|
||||
this._damageBounds.right = this._damageBounds.bottom = 0;
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
if (this._logo) {
|
||||
this.resize(this._logo.width, this._logo.height);
|
||||
this.imageRect(0, 0, this._logo.type, this._logo.data);
|
||||
} else {
|
||||
this.resize(240, 20);
|
||||
this._drawCtx.clearRect(0, 0, this._fb_width, this._fb_height);
|
||||
}
|
||||
this.flip();
|
||||
}
|
||||
|
||||
pending() {
|
||||
return this._renderQ.length > 0;
|
||||
}
|
||||
|
||||
flush() {
|
||||
if (this._renderQ.length === 0) {
|
||||
this.onflush();
|
||||
} else {
|
||||
this._flushing = true;
|
||||
}
|
||||
}
|
||||
|
||||
fillRect(x, y, width, height, color, from_queue) {
|
||||
if (this._renderQ.length !== 0 && !from_queue) {
|
||||
this._renderQ_push({
|
||||
'type': 'fill',
|
||||
'x': x,
|
||||
'y': y,
|
||||
'width': width,
|
||||
'height': height,
|
||||
'color': color
|
||||
});
|
||||
} else {
|
||||
this._setFillColor(color);
|
||||
this._drawCtx.fillRect(x, y, width, height);
|
||||
this._damage(x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
copyImage(old_x, old_y, new_x, new_y, w, h, from_queue) {
|
||||
if (this._renderQ.length !== 0 && !from_queue) {
|
||||
this._renderQ_push({
|
||||
'type': 'copy',
|
||||
'old_x': old_x,
|
||||
'old_y': old_y,
|
||||
'x': new_x,
|
||||
'y': new_y,
|
||||
'width': w,
|
||||
'height': h,
|
||||
});
|
||||
} else {
|
||||
// Due to this bug among others [1] we need to disable the image-smoothing to
|
||||
// avoid getting a blur effect when copying data.
|
||||
//
|
||||
// 1. https://bugzilla.mozilla.org/show_bug.cgi?id=1194719
|
||||
//
|
||||
// We need to set these every time since all properties are reset
|
||||
// when the the size is changed
|
||||
this._drawCtx.mozImageSmoothingEnabled = false;
|
||||
this._drawCtx.webkitImageSmoothingEnabled = false;
|
||||
this._drawCtx.msImageSmoothingEnabled = false;
|
||||
this._drawCtx.imageSmoothingEnabled = false;
|
||||
|
||||
this._drawCtx.drawImage(this._backbuffer,
|
||||
old_x, old_y, w, h,
|
||||
new_x, new_y, w, h);
|
||||
this._damage(new_x, new_y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
imageRect(x, y, mime, arr) {
|
||||
const img = new Image();
|
||||
img.src = "data: " + mime + ";base64," + Base64.encode(arr);
|
||||
this._renderQ_push({
|
||||
'type': 'img',
|
||||
'img': img,
|
||||
'x': x,
|
||||
'y': y
|
||||
});
|
||||
}
|
||||
|
||||
// start updating a tile
|
||||
startTile(x, y, width, height, color) {
|
||||
this._tile_x = x;
|
||||
this._tile_y = y;
|
||||
if (width === 16 && height === 16) {
|
||||
this._tile = this._tile16x16;
|
||||
} else {
|
||||
this._tile = this._drawCtx.createImageData(width, height);
|
||||
}
|
||||
|
||||
const red = color[2];
|
||||
const green = color[1];
|
||||
const blue = color[0];
|
||||
|
||||
const data = this._tile.data;
|
||||
for (let i = 0; i < width * height * 4; i += 4) {
|
||||
data[i] = red;
|
||||
data[i + 1] = green;
|
||||
data[i + 2] = blue;
|
||||
data[i + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// update sub-rectangle of the current tile
|
||||
subTile(x, y, w, h, color) {
|
||||
const red = color[2];
|
||||
const green = color[1];
|
||||
const blue = color[0];
|
||||
const xend = x + w;
|
||||
const yend = y + h;
|
||||
|
||||
const data = this._tile.data;
|
||||
const width = this._tile.width;
|
||||
for (let j = y; j < yend; j++) {
|
||||
for (let i = x; i < xend; i++) {
|
||||
const p = (i + (j * width)) * 4;
|
||||
data[p] = red;
|
||||
data[p + 1] = green;
|
||||
data[p + 2] = blue;
|
||||
data[p + 3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// draw the current tile to the screen
|
||||
finishTile() {
|
||||
this._drawCtx.putImageData(this._tile, this._tile_x, this._tile_y);
|
||||
this._damage(this._tile_x, this._tile_y,
|
||||
this._tile.width, this._tile.height);
|
||||
}
|
||||
|
||||
blitImage(x, y, width, height, arr, offset, from_queue) {
|
||||
if (this._renderQ.length !== 0 && !from_queue) {
|
||||
// NB(directxman12): it's technically more performant here to use preallocated arrays,
|
||||
// but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
|
||||
// this probably isn't getting called *nearly* as much
|
||||
const new_arr = new Uint8Array(width * height * 4);
|
||||
new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length));
|
||||
this._renderQ_push({
|
||||
'type': 'blit',
|
||||
'data': new_arr,
|
||||
'x': x,
|
||||
'y': y,
|
||||
'width': width,
|
||||
'height': height,
|
||||
});
|
||||
} else {
|
||||
this._bgrxImageData(x, y, width, height, arr, offset);
|
||||
}
|
||||
}
|
||||
|
||||
blitRgbImage(x, y, width, height, arr, offset, from_queue) {
|
||||
if (this._renderQ.length !== 0 && !from_queue) {
|
||||
// NB(directxman12): it's technically more performant here to use preallocated arrays,
|
||||
// but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
|
||||
// this probably isn't getting called *nearly* as much
|
||||
const new_arr = new Uint8Array(width * height * 3);
|
||||
new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length));
|
||||
this._renderQ_push({
|
||||
'type': 'blitRgb',
|
||||
'data': new_arr,
|
||||
'x': x,
|
||||
'y': y,
|
||||
'width': width,
|
||||
'height': height,
|
||||
});
|
||||
} else {
|
||||
this._rgbImageData(x, y, width, height, arr, offset);
|
||||
}
|
||||
}
|
||||
|
||||
blitRgbxImage(x, y, width, height, arr, offset, from_queue) {
|
||||
if (this._renderQ.length !== 0 && !from_queue) {
|
||||
// NB(directxman12): it's technically more performant here to use preallocated arrays,
|
||||
// but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
|
||||
// this probably isn't getting called *nearly* as much
|
||||
const new_arr = new Uint8Array(width * height * 4);
|
||||
new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length));
|
||||
this._renderQ_push({
|
||||
'type': 'blitRgbx',
|
||||
'data': new_arr,
|
||||
'x': x,
|
||||
'y': y,
|
||||
'width': width,
|
||||
'height': height,
|
||||
});
|
||||
} else {
|
||||
this._rgbxImageData(x, y, width, height, arr, offset);
|
||||
}
|
||||
}
|
||||
|
||||
drawImage(img, x, y) {
|
||||
this._drawCtx.drawImage(img, x, y);
|
||||
this._damage(x, y, img.width, img.height);
|
||||
}
|
||||
|
||||
autoscale(containerWidth, containerHeight) {
|
||||
let scaleRatio;
|
||||
|
||||
if (containerWidth === 0 || containerHeight === 0) {
|
||||
scaleRatio = 0;
|
||||
|
||||
} else {
|
||||
|
||||
const vp = this._viewportLoc;
|
||||
const targetAspectRatio = containerWidth / containerHeight;
|
||||
const fbAspectRatio = vp.w / vp.h;
|
||||
|
||||
if (fbAspectRatio >= targetAspectRatio) {
|
||||
scaleRatio = containerWidth / vp.w;
|
||||
} else {
|
||||
scaleRatio = containerHeight / vp.h;
|
||||
}
|
||||
}
|
||||
|
||||
this._rescale(scaleRatio);
|
||||
}
|
||||
|
||||
// ===== PRIVATE METHODS =====
|
||||
|
||||
_rescale(factor) {
|
||||
this._scale = factor;
|
||||
const vp = this._viewportLoc;
|
||||
|
||||
// NB(directxman12): If you set the width directly, or set the
|
||||
// style width to a number, the canvas is cleared.
|
||||
// However, if you set the style width to a string
|
||||
// ('NNNpx'), the canvas is scaled without clearing.
|
||||
const width = factor * vp.w + 'px';
|
||||
const height = factor * vp.h + 'px';
|
||||
|
||||
if ((this._target.style.width !== width) ||
|
||||
(this._target.style.height !== height)) {
|
||||
this._target.style.width = width;
|
||||
this._target.style.height = height;
|
||||
}
|
||||
}
|
||||
|
||||
_setFillColor(color) {
|
||||
const newStyle = 'rgb(' + color[2] + ',' + color[1] + ',' + color[0] + ')';
|
||||
if (newStyle !== this._prevDrawStyle) {
|
||||
this._drawCtx.fillStyle = newStyle;
|
||||
this._prevDrawStyle = newStyle;
|
||||
}
|
||||
}
|
||||
|
||||
_rgbImageData(x, y, width, height, arr, offset) {
|
||||
const img = this._drawCtx.createImageData(width, height);
|
||||
const data = img.data;
|
||||
for (let i = 0, j = offset; i < width * height * 4; i += 4, j += 3) {
|
||||
data[i] = arr[j];
|
||||
data[i + 1] = arr[j + 1];
|
||||
data[i + 2] = arr[j + 2];
|
||||
data[i + 3] = 255; // Alpha
|
||||
}
|
||||
this._drawCtx.putImageData(img, x, y);
|
||||
this._damage(x, y, img.width, img.height);
|
||||
}
|
||||
|
||||
_bgrxImageData(x, y, width, height, arr, offset) {
|
||||
const img = this._drawCtx.createImageData(width, height);
|
||||
const data = img.data;
|
||||
for (let i = 0, j = offset; i < width * height * 4; i += 4, j += 4) {
|
||||
data[i] = arr[j + 2];
|
||||
data[i + 1] = arr[j + 1];
|
||||
data[i + 2] = arr[j];
|
||||
data[i + 3] = 255; // Alpha
|
||||
}
|
||||
this._drawCtx.putImageData(img, x, y);
|
||||
this._damage(x, y, img.width, img.height);
|
||||
}
|
||||
|
||||
_rgbxImageData(x, y, width, height, arr, offset) {
|
||||
// NB(directxman12): arr must be an Type Array view
|
||||
let img;
|
||||
if (supportsImageMetadata) {
|
||||
img = new ImageData(new Uint8ClampedArray(arr.buffer, arr.byteOffset, width * height * 4), width, height);
|
||||
} else {
|
||||
img = this._drawCtx.createImageData(width, height);
|
||||
img.data.set(new Uint8ClampedArray(arr.buffer, arr.byteOffset, width * height * 4));
|
||||
}
|
||||
this._drawCtx.putImageData(img, x, y);
|
||||
this._damage(x, y, img.width, img.height);
|
||||
}
|
||||
|
||||
_renderQ_push(action) {
|
||||
this._renderQ.push(action);
|
||||
if (this._renderQ.length === 1) {
|
||||
// If this can be rendered immediately it will be, otherwise
|
||||
// the scanner will wait for the relevant event
|
||||
this._scan_renderQ();
|
||||
}
|
||||
}
|
||||
|
||||
_resume_renderQ() {
|
||||
// "this" is the object that is ready, not the
|
||||
// display object
|
||||
this.removeEventListener('load', this._noVNC_display._resume_renderQ);
|
||||
this._noVNC_display._scan_renderQ();
|
||||
}
|
||||
|
||||
_scan_renderQ() {
|
||||
let ready = true;
|
||||
while (ready && this._renderQ.length > 0) {
|
||||
const a = this._renderQ[0];
|
||||
switch (a.type) {
|
||||
case 'flip':
|
||||
this.flip(true);
|
||||
break;
|
||||
case 'copy':
|
||||
this.copyImage(a.old_x, a.old_y, a.x, a.y, a.width, a.height, true);
|
||||
break;
|
||||
case 'fill':
|
||||
this.fillRect(a.x, a.y, a.width, a.height, a.color, true);
|
||||
break;
|
||||
case 'blit':
|
||||
this.blitImage(a.x, a.y, a.width, a.height, a.data, 0, true);
|
||||
break;
|
||||
case 'blitRgb':
|
||||
this.blitRgbImage(a.x, a.y, a.width, a.height, a.data, 0, true);
|
||||
break;
|
||||
case 'blitRgbx':
|
||||
this.blitRgbxImage(a.x, a.y, a.width, a.height, a.data, 0, true);
|
||||
break;
|
||||
case 'img':
|
||||
if (a.img.complete) {
|
||||
this.drawImage(a.img, a.x, a.y);
|
||||
} else {
|
||||
a.img._noVNC_display = this;
|
||||
a.img.addEventListener('load', this._resume_renderQ);
|
||||
// We need to wait for this image to 'load'
|
||||
// to keep things in-order
|
||||
ready = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (ready) {
|
||||
this._renderQ.shift();
|
||||
}
|
||||
}
|
||||
|
||||
if (this._renderQ.length === 0 && this._flushing) {
|
||||
this._flushing = false;
|
||||
this.onflush();
|
||||
}
|
||||
}
|
||||
}
|
41
public/novnc/core/encodings.js
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*/
|
||||
|
||||
export const encodings = {
|
||||
encodingRaw: 0,
|
||||
encodingCopyRect: 1,
|
||||
encodingRRE: 2,
|
||||
encodingHextile: 5,
|
||||
encodingTight: 7,
|
||||
encodingTightPNG: -260,
|
||||
|
||||
pseudoEncodingQualityLevel9: -23,
|
||||
pseudoEncodingQualityLevel0: -32,
|
||||
pseudoEncodingDesktopSize: -223,
|
||||
pseudoEncodingLastRect: -224,
|
||||
pseudoEncodingCursor: -239,
|
||||
pseudoEncodingQEMUExtendedKeyEvent: -258,
|
||||
pseudoEncodingExtendedDesktopSize: -308,
|
||||
pseudoEncodingXvp: -309,
|
||||
pseudoEncodingFence: -312,
|
||||
pseudoEncodingContinuousUpdates: -313,
|
||||
pseudoEncodingCompressLevel9: -247,
|
||||
pseudoEncodingCompressLevel0: -256,
|
||||
};
|
||||
|
||||
export function encodingName(num) {
|
||||
switch (num) {
|
||||
case encodings.encodingRaw: return "Raw";
|
||||
case encodings.encodingCopyRect: return "CopyRect";
|
||||
case encodings.encodingRRE: return "RRE";
|
||||
case encodings.encodingHextile: return "Hextile";
|
||||
case encodings.encodingTight: return "Tight";
|
||||
case encodings.encodingTightPNG: return "TightPNG";
|
||||
default: return "[unknown encoding " + num + "]";
|
||||
}
|
||||
}
|
38
public/novnc/core/inflator.js
Normal file
@ -0,0 +1,38 @@
|
||||
import { inflateInit, inflate, inflateReset } from "../vendor/pako/lib/zlib/inflate.js";
|
||||
import ZStream from "../vendor/pako/lib/zlib/zstream.js";
|
||||
|
||||
export default class Inflate {
|
||||
constructor() {
|
||||
this.strm = new ZStream();
|
||||
this.chunkSize = 1024 * 10 * 10;
|
||||
this.strm.output = new Uint8Array(this.chunkSize);
|
||||
this.windowBits = 5;
|
||||
|
||||
inflateInit(this.strm, this.windowBits);
|
||||
}
|
||||
|
||||
inflate(data, flush, expected) {
|
||||
this.strm.input = data;
|
||||
this.strm.avail_in = this.strm.input.length;
|
||||
this.strm.next_in = 0;
|
||||
this.strm.next_out = 0;
|
||||
|
||||
// resize our output buffer if it's too small
|
||||
// (we could just use multiple chunks, but that would cause an extra
|
||||
// allocation each time to flatten the chunks)
|
||||
if (expected > this.chunkSize) {
|
||||
this.chunkSize = expected;
|
||||
this.strm.output = new Uint8Array(this.chunkSize);
|
||||
}
|
||||
|
||||
this.strm.avail_out = this.chunkSize;
|
||||
|
||||
inflate(this.strm, flush);
|
||||
|
||||
return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
|
||||
}
|
||||
|
||||
reset() {
|
||||
inflateReset(this.strm);
|
||||
}
|
||||
}
|
307
public/novnc/core/input/domkeytable.js
Normal file
@ -0,0 +1,307 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
import KeyTable from "./keysym.js";
|
||||
|
||||
/*
|
||||
* Mapping between HTML key values and VNC/X11 keysyms for "special"
|
||||
* keys that cannot be handled via their Unicode codepoint.
|
||||
*
|
||||
* See https://www.w3.org/TR/uievents-key/ for possible values.
|
||||
*/
|
||||
|
||||
const DOMKeyTable = {};
|
||||
|
||||
function addStandard(key, standard) {
|
||||
if (standard === undefined) throw new Error("Undefined keysym for key \"" + key + "\"");
|
||||
if (key in DOMKeyTable) throw new Error("Duplicate entry for key \"" + key + "\"");
|
||||
DOMKeyTable[key] = [standard, standard, standard, standard];
|
||||
}
|
||||
|
||||
function addLeftRight(key, left, right) {
|
||||
if (left === undefined) throw new Error("Undefined keysym for key \"" + key + "\"");
|
||||
if (right === undefined) throw new Error("Undefined keysym for key \"" + key + "\"");
|
||||
if (key in DOMKeyTable) throw new Error("Duplicate entry for key \"" + key + "\"");
|
||||
DOMKeyTable[key] = [left, left, right, left];
|
||||
}
|
||||
|
||||
function addNumpad(key, standard, numpad) {
|
||||
if (standard === undefined) throw new Error("Undefined keysym for key \"" + key + "\"");
|
||||
if (numpad === undefined) throw new Error("Undefined keysym for key \"" + key + "\"");
|
||||
if (key in DOMKeyTable) throw new Error("Duplicate entry for key \"" + key + "\"");
|
||||
DOMKeyTable[key] = [standard, standard, standard, numpad];
|
||||
}
|
||||
|
||||
// 2.2. Modifier Keys
|
||||
|
||||
addLeftRight("Alt", KeyTable.XK_Alt_L, KeyTable.XK_Alt_R);
|
||||
addStandard("AltGraph", KeyTable.XK_ISO_Level3_Shift);
|
||||
addStandard("CapsLock", KeyTable.XK_Caps_Lock);
|
||||
addLeftRight("Control", KeyTable.XK_Control_L, KeyTable.XK_Control_R);
|
||||
// - Fn
|
||||
// - FnLock
|
||||
addLeftRight("Hyper", KeyTable.XK_Super_L, KeyTable.XK_Super_R);
|
||||
addLeftRight("Meta", KeyTable.XK_Super_L, KeyTable.XK_Super_R);
|
||||
addStandard("NumLock", KeyTable.XK_Num_Lock);
|
||||
addStandard("ScrollLock", KeyTable.XK_Scroll_Lock);
|
||||
addLeftRight("Shift", KeyTable.XK_Shift_L, KeyTable.XK_Shift_R);
|
||||
addLeftRight("Super", KeyTable.XK_Super_L, KeyTable.XK_Super_R);
|
||||
// - Symbol
|
||||
// - SymbolLock
|
||||
|
||||
// 2.3. Whitespace Keys
|
||||
|
||||
addNumpad("Enter", KeyTable.XK_Return, KeyTable.XK_KP_Enter);
|
||||
addStandard("Tab", KeyTable.XK_Tab);
|
||||
addNumpad(" ", KeyTable.XK_space, KeyTable.XK_KP_Space);
|
||||
|
||||
// 2.4. Navigation Keys
|
||||
|
||||
addNumpad("ArrowDown", KeyTable.XK_Down, KeyTable.XK_KP_Down);
|
||||
addNumpad("ArrowUp", KeyTable.XK_Up, KeyTable.XK_KP_Up);
|
||||
addNumpad("ArrowLeft", KeyTable.XK_Left, KeyTable.XK_KP_Left);
|
||||
addNumpad("ArrowRight", KeyTable.XK_Right, KeyTable.XK_KP_Right);
|
||||
addNumpad("End", KeyTable.XK_End, KeyTable.XK_KP_End);
|
||||
addNumpad("Home", KeyTable.XK_Home, KeyTable.XK_KP_Home);
|
||||
addNumpad("PageDown", KeyTable.XK_Next, KeyTable.XK_KP_Next);
|
||||
addNumpad("PageUp", KeyTable.XK_Prior, KeyTable.XK_KP_Prior);
|
||||
|
||||
// 2.5. Editing Keys
|
||||
|
||||
addStandard("Backspace", KeyTable.XK_BackSpace);
|
||||
addNumpad("Clear", KeyTable.XK_Clear, KeyTable.XK_KP_Begin);
|
||||
addStandard("Copy", KeyTable.XF86XK_Copy);
|
||||
// - CrSel
|
||||
addStandard("Cut", KeyTable.XF86XK_Cut);
|
||||
addNumpad("Delete", KeyTable.XK_Delete, KeyTable.XK_KP_Delete);
|
||||
// - EraseEof
|
||||
// - ExSel
|
||||
addNumpad("Insert", KeyTable.XK_Insert, KeyTable.XK_KP_Insert);
|
||||
addStandard("Paste", KeyTable.XF86XK_Paste);
|
||||
addStandard("Redo", KeyTable.XK_Redo);
|
||||
addStandard("Undo", KeyTable.XK_Undo);
|
||||
|
||||
// 2.6. UI Keys
|
||||
|
||||
// - Accept
|
||||
// - Again (could just be XK_Redo)
|
||||
// - Attn
|
||||
addStandard("Cancel", KeyTable.XK_Cancel);
|
||||
addStandard("ContextMenu", KeyTable.XK_Menu);
|
||||
addStandard("Escape", KeyTable.XK_Escape);
|
||||
addStandard("Execute", KeyTable.XK_Execute);
|
||||
addStandard("Find", KeyTable.XK_Find);
|
||||
addStandard("Help", KeyTable.XK_Help);
|
||||
addStandard("Pause", KeyTable.XK_Pause);
|
||||
// - Play
|
||||
// - Props
|
||||
addStandard("Select", KeyTable.XK_Select);
|
||||
addStandard("ZoomIn", KeyTable.XF86XK_ZoomIn);
|
||||
addStandard("ZoomOut", KeyTable.XF86XK_ZoomOut);
|
||||
|
||||
// 2.7. Device Keys
|
||||
|
||||
addStandard("BrightnessDown", KeyTable.XF86XK_MonBrightnessDown);
|
||||
addStandard("BrightnessUp", KeyTable.XF86XK_MonBrightnessUp);
|
||||
addStandard("Eject", KeyTable.XF86XK_Eject);
|
||||
addStandard("LogOff", KeyTable.XF86XK_LogOff);
|
||||
addStandard("Power", KeyTable.XF86XK_PowerOff);
|
||||
addStandard("PowerOff", KeyTable.XF86XK_PowerDown);
|
||||
addStandard("PrintScreen", KeyTable.XK_Print);
|
||||
addStandard("Hibernate", KeyTable.XF86XK_Hibernate);
|
||||
addStandard("Standby", KeyTable.XF86XK_Standby);
|
||||
addStandard("WakeUp", KeyTable.XF86XK_WakeUp);
|
||||
|
||||
// 2.8. IME and Composition Keys
|
||||
|
||||
addStandard("AllCandidates", KeyTable.XK_MultipleCandidate);
|
||||
addStandard("Alphanumeric", KeyTable.XK_Eisu_Shift); // could also be _Eisu_Toggle
|
||||
addStandard("CodeInput", KeyTable.XK_Codeinput);
|
||||
addStandard("Compose", KeyTable.XK_Multi_key);
|
||||
addStandard("Convert", KeyTable.XK_Henkan);
|
||||
// - Dead
|
||||
// - FinalMode
|
||||
addStandard("GroupFirst", KeyTable.XK_ISO_First_Group);
|
||||
addStandard("GroupLast", KeyTable.XK_ISO_Last_Group);
|
||||
addStandard("GroupNext", KeyTable.XK_ISO_Next_Group);
|
||||
addStandard("GroupPrevious", KeyTable.XK_ISO_Prev_Group);
|
||||
// - ModeChange (XK_Mode_switch is often used for AltGr)
|
||||
// - NextCandidate
|
||||
addStandard("NonConvert", KeyTable.XK_Muhenkan);
|
||||
addStandard("PreviousCandidate", KeyTable.XK_PreviousCandidate);
|
||||
// - Process
|
||||
addStandard("SingleCandidate", KeyTable.XK_SingleCandidate);
|
||||
addStandard("HangulMode", KeyTable.XK_Hangul);
|
||||
addStandard("HanjaMode", KeyTable.XK_Hangul_Hanja);
|
||||
addStandard("JunjuaMode", KeyTable.XK_Hangul_Jeonja);
|
||||
addStandard("Eisu", KeyTable.XK_Eisu_toggle);
|
||||
addStandard("Hankaku", KeyTable.XK_Hankaku);
|
||||
addStandard("Hiragana", KeyTable.XK_Hiragana);
|
||||
addStandard("HiraganaKatakana", KeyTable.XK_Hiragana_Katakana);
|
||||
addStandard("KanaMode", KeyTable.XK_Kana_Shift); // could also be _Kana_Lock
|
||||
addStandard("KanjiMode", KeyTable.XK_Kanji);
|
||||
addStandard("Katakana", KeyTable.XK_Katakana);
|
||||
addStandard("Romaji", KeyTable.XK_Romaji);
|
||||
addStandard("Zenkaku", KeyTable.XK_Zenkaku);
|
||||
addStandard("ZenkakuHanaku", KeyTable.XK_Zenkaku_Hankaku);
|
||||
|
||||
// 2.9. General-Purpose Function Keys
|
||||
|
||||
addStandard("F1", KeyTable.XK_F1);
|
||||
addStandard("F2", KeyTable.XK_F2);
|
||||
addStandard("F3", KeyTable.XK_F3);
|
||||
addStandard("F4", KeyTable.XK_F4);
|
||||
addStandard("F5", KeyTable.XK_F5);
|
||||
addStandard("F6", KeyTable.XK_F6);
|
||||
addStandard("F7", KeyTable.XK_F7);
|
||||
addStandard("F8", KeyTable.XK_F8);
|
||||
addStandard("F9", KeyTable.XK_F9);
|
||||
addStandard("F10", KeyTable.XK_F10);
|
||||
addStandard("F11", KeyTable.XK_F11);
|
||||
addStandard("F12", KeyTable.XK_F12);
|
||||
addStandard("F13", KeyTable.XK_F13);
|
||||
addStandard("F14", KeyTable.XK_F14);
|
||||
addStandard("F15", KeyTable.XK_F15);
|
||||
addStandard("F16", KeyTable.XK_F16);
|
||||
addStandard("F17", KeyTable.XK_F17);
|
||||
addStandard("F18", KeyTable.XK_F18);
|
||||
addStandard("F19", KeyTable.XK_F19);
|
||||
addStandard("F20", KeyTable.XK_F20);
|
||||
addStandard("F21", KeyTable.XK_F21);
|
||||
addStandard("F22", KeyTable.XK_F22);
|
||||
addStandard("F23", KeyTable.XK_F23);
|
||||
addStandard("F24", KeyTable.XK_F24);
|
||||
addStandard("F25", KeyTable.XK_F25);
|
||||
addStandard("F26", KeyTable.XK_F26);
|
||||
addStandard("F27", KeyTable.XK_F27);
|
||||
addStandard("F28", KeyTable.XK_F28);
|
||||
addStandard("F29", KeyTable.XK_F29);
|
||||
addStandard("F30", KeyTable.XK_F30);
|
||||
addStandard("F31", KeyTable.XK_F31);
|
||||
addStandard("F32", KeyTable.XK_F32);
|
||||
addStandard("F33", KeyTable.XK_F33);
|
||||
addStandard("F34", KeyTable.XK_F34);
|
||||
addStandard("F35", KeyTable.XK_F35);
|
||||
// - Soft1...
|
||||
|
||||
// 2.10. Multimedia Keys
|
||||
|
||||
// - ChannelDown
|
||||
// - ChannelUp
|
||||
addStandard("Close", KeyTable.XF86XK_Close);
|
||||
addStandard("MailForward", KeyTable.XF86XK_MailForward);
|
||||
addStandard("MailReply", KeyTable.XF86XK_Reply);
|
||||
addStandard("MainSend", KeyTable.XF86XK_Send);
|
||||
addStandard("MediaFastForward", KeyTable.XF86XK_AudioForward);
|
||||
addStandard("MediaPause", KeyTable.XF86XK_AudioPause);
|
||||
addStandard("MediaPlay", KeyTable.XF86XK_AudioPlay);
|
||||
addStandard("MediaRecord", KeyTable.XF86XK_AudioRecord);
|
||||
addStandard("MediaRewind", KeyTable.XF86XK_AudioRewind);
|
||||
addStandard("MediaStop", KeyTable.XF86XK_AudioStop);
|
||||
addStandard("MediaTrackNext", KeyTable.XF86XK_AudioNext);
|
||||
addStandard("MediaTrackPrevious", KeyTable.XF86XK_AudioPrev);
|
||||
addStandard("New", KeyTable.XF86XK_New);
|
||||
addStandard("Open", KeyTable.XF86XK_Open);
|
||||
addStandard("Print", KeyTable.XK_Print);
|
||||
addStandard("Save", KeyTable.XF86XK_Save);
|
||||
addStandard("SpellCheck", KeyTable.XF86XK_Spell);
|
||||
|
||||
// 2.11. Multimedia Numpad Keys
|
||||
|
||||
// - Key11
|
||||
// - Key12
|
||||
|
||||
// 2.12. Audio Keys
|
||||
|
||||
// - AudioBalanceLeft
|
||||
// - AudioBalanceRight
|
||||
// - AudioBassDown
|
||||
// - AudioBassBoostDown
|
||||
// - AudioBassBoostToggle
|
||||
// - AudioBassBoostUp
|
||||
// - AudioBassUp
|
||||
// - AudioFaderFront
|
||||
// - AudioFaderRear
|
||||
// - AudioSurroundModeNext
|
||||
// - AudioTrebleDown
|
||||
// - AudioTrebleUp
|
||||
addStandard("AudioVolumeDown", KeyTable.XF86XK_AudioLowerVolume);
|
||||
addStandard("AudioVolumeUp", KeyTable.XF86XK_AudioRaiseVolume);
|
||||
addStandard("AudioVolumeMute", KeyTable.XF86XK_AudioMute);
|
||||
// - MicrophoneToggle
|
||||
// - MicrophoneVolumeDown
|
||||
// - MicrophoneVolumeUp
|
||||
addStandard("MicrophoneVolumeMute", KeyTable.XF86XK_AudioMicMute);
|
||||
|
||||
// 2.13. Speech Keys
|
||||
|
||||
// - SpeechCorrectionList
|
||||
// - SpeechInputToggle
|
||||
|
||||
// 2.14. Application Keys
|
||||
|
||||
addStandard("LaunchCalculator", KeyTable.XF86XK_Calculator);
|
||||
addStandard("LaunchCalendar", KeyTable.XF86XK_Calendar);
|
||||
addStandard("LaunchMail", KeyTable.XF86XK_Mail);
|
||||
addStandard("LaunchMediaPlayer", KeyTable.XF86XK_AudioMedia);
|
||||
addStandard("LaunchMusicPlayer", KeyTable.XF86XK_Music);
|
||||
addStandard("LaunchMyComputer", KeyTable.XF86XK_MyComputer);
|
||||
addStandard("LaunchPhone", KeyTable.XF86XK_Phone);
|
||||
addStandard("LaunchScreenSaver", KeyTable.XF86XK_ScreenSaver);
|
||||
addStandard("LaunchSpreadsheet", KeyTable.XF86XK_Excel);
|
||||
addStandard("LaunchWebBrowser", KeyTable.XF86XK_WWW);
|
||||
addStandard("LaunchWebCam", KeyTable.XF86XK_WebCam);
|
||||
addStandard("LaunchWordProcessor", KeyTable.XF86XK_Word);
|
||||
|
||||
// 2.15. Browser Keys
|
||||
|
||||
addStandard("BrowserBack", KeyTable.XF86XK_Back);
|
||||
addStandard("BrowserFavorites", KeyTable.XF86XK_Favorites);
|
||||
addStandard("BrowserForward", KeyTable.XF86XK_Forward);
|
||||
addStandard("BrowserHome", KeyTable.XF86XK_HomePage);
|
||||
addStandard("BrowserRefresh", KeyTable.XF86XK_Refresh);
|
||||
addStandard("BrowserSearch", KeyTable.XF86XK_Search);
|
||||
addStandard("BrowserStop", KeyTable.XF86XK_Stop);
|
||||
|
||||
// 2.16. Mobile Phone Keys
|
||||
|
||||
// - A whole bunch...
|
||||
|
||||
// 2.17. TV Keys
|
||||
|
||||
// - A whole bunch...
|
||||
|
||||
// 2.18. Media Controller Keys
|
||||
|
||||
// - A whole bunch...
|
||||
addStandard("Dimmer", KeyTable.XF86XK_BrightnessAdjust);
|
||||
addStandard("MediaAudioTrack", KeyTable.XF86XK_AudioCycleTrack);
|
||||
addStandard("RandomToggle", KeyTable.XF86XK_AudioRandomPlay);
|
||||
addStandard("SplitScreenToggle", KeyTable.XF86XK_SplitScreen);
|
||||
addStandard("Subtitle", KeyTable.XF86XK_Subtitle);
|
||||
addStandard("VideoModeNext", KeyTable.XF86XK_Next_VMode);
|
||||
|
||||
// Extra: Numpad
|
||||
|
||||
addNumpad("=", KeyTable.XK_equal, KeyTable.XK_KP_Equal);
|
||||
addNumpad("+", KeyTable.XK_plus, KeyTable.XK_KP_Add);
|
||||
addNumpad("-", KeyTable.XK_minus, KeyTable.XK_KP_Subtract);
|
||||
addNumpad("*", KeyTable.XK_asterisk, KeyTable.XK_KP_Multiply);
|
||||
addNumpad("/", KeyTable.XK_slash, KeyTable.XK_KP_Divide);
|
||||
addNumpad(".", KeyTable.XK_period, KeyTable.XK_KP_Decimal);
|
||||
addNumpad(",", KeyTable.XK_comma, KeyTable.XK_KP_Separator);
|
||||
addNumpad("0", KeyTable.XK_0, KeyTable.XK_KP_0);
|
||||
addNumpad("1", KeyTable.XK_1, KeyTable.XK_KP_1);
|
||||
addNumpad("2", KeyTable.XK_2, KeyTable.XK_KP_2);
|
||||
addNumpad("3", KeyTable.XK_3, KeyTable.XK_KP_3);
|
||||
addNumpad("4", KeyTable.XK_4, KeyTable.XK_KP_4);
|
||||
addNumpad("5", KeyTable.XK_5, KeyTable.XK_KP_5);
|
||||
addNumpad("6", KeyTable.XK_6, KeyTable.XK_KP_6);
|
||||
addNumpad("7", KeyTable.XK_7, KeyTable.XK_KP_7);
|
||||
addNumpad("8", KeyTable.XK_8, KeyTable.XK_KP_8);
|
||||
addNumpad("9", KeyTable.XK_9, KeyTable.XK_KP_9);
|
||||
|
||||
export default DOMKeyTable;
|
129
public/novnc/core/input/fixedkeys.js
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Fallback mapping between HTML key codes (physical keys) and
|
||||
* HTML key values. This only works for keys that don't vary
|
||||
* between layouts. We also omit those who manage fine by mapping the
|
||||
* Unicode representation.
|
||||
*
|
||||
* See https://www.w3.org/TR/uievents-code/ for possible codes.
|
||||
* See https://www.w3.org/TR/uievents-key/ for possible values.
|
||||
*/
|
||||
|
||||
/* eslint-disable key-spacing */
|
||||
|
||||
export default {
|
||||
|
||||
// 3.1.1.1. Writing System Keys
|
||||
|
||||
'Backspace': 'Backspace',
|
||||
|
||||
// 3.1.1.2. Functional Keys
|
||||
|
||||
'AltLeft': 'Alt',
|
||||
'AltRight': 'Alt', // This could also be 'AltGraph'
|
||||
'CapsLock': 'CapsLock',
|
||||
'ContextMenu': 'ContextMenu',
|
||||
'ControlLeft': 'Control',
|
||||
'ControlRight': 'Control',
|
||||
'Enter': 'Enter',
|
||||
'MetaLeft': 'Meta',
|
||||
'MetaRight': 'Meta',
|
||||
'ShiftLeft': 'Shift',
|
||||
'ShiftRight': 'Shift',
|
||||
'Tab': 'Tab',
|
||||
// FIXME: Japanese/Korean keys
|
||||
|
||||
// 3.1.2. Control Pad Section
|
||||
|
||||
'Delete': 'Delete',
|
||||
'End': 'End',
|
||||
'Help': 'Help',
|
||||
'Home': 'Home',
|
||||
'Insert': 'Insert',
|
||||
'PageDown': 'PageDown',
|
||||
'PageUp': 'PageUp',
|
||||
|
||||
// 3.1.3. Arrow Pad Section
|
||||
|
||||
'ArrowDown': 'ArrowDown',
|
||||
'ArrowLeft': 'ArrowLeft',
|
||||
'ArrowRight': 'ArrowRight',
|
||||
'ArrowUp': 'ArrowUp',
|
||||
|
||||
// 3.1.4. Numpad Section
|
||||
|
||||
'NumLock': 'NumLock',
|
||||
'NumpadBackspace': 'Backspace',
|
||||
'NumpadClear': 'Clear',
|
||||
|
||||
// 3.1.5. Function Section
|
||||
|
||||
'Escape': 'Escape',
|
||||
'F1': 'F1',
|
||||
'F2': 'F2',
|
||||
'F3': 'F3',
|
||||
'F4': 'F4',
|
||||
'F5': 'F5',
|
||||
'F6': 'F6',
|
||||
'F7': 'F7',
|
||||
'F8': 'F8',
|
||||
'F9': 'F9',
|
||||
'F10': 'F10',
|
||||
'F11': 'F11',
|
||||
'F12': 'F12',
|
||||
'F13': 'F13',
|
||||
'F14': 'F14',
|
||||
'F15': 'F15',
|
||||
'F16': 'F16',
|
||||
'F17': 'F17',
|
||||
'F18': 'F18',
|
||||
'F19': 'F19',
|
||||
'F20': 'F20',
|
||||
'F21': 'F21',
|
||||
'F22': 'F22',
|
||||
'F23': 'F23',
|
||||
'F24': 'F24',
|
||||
'F25': 'F25',
|
||||
'F26': 'F26',
|
||||
'F27': 'F27',
|
||||
'F28': 'F28',
|
||||
'F29': 'F29',
|
||||
'F30': 'F30',
|
||||
'F31': 'F31',
|
||||
'F32': 'F32',
|
||||
'F33': 'F33',
|
||||
'F34': 'F34',
|
||||
'F35': 'F35',
|
||||
'PrintScreen': 'PrintScreen',
|
||||
'ScrollLock': 'ScrollLock',
|
||||
'Pause': 'Pause',
|
||||
|
||||
// 3.1.6. Media Keys
|
||||
|
||||
'BrowserBack': 'BrowserBack',
|
||||
'BrowserFavorites': 'BrowserFavorites',
|
||||
'BrowserForward': 'BrowserForward',
|
||||
'BrowserHome': 'BrowserHome',
|
||||
'BrowserRefresh': 'BrowserRefresh',
|
||||
'BrowserSearch': 'BrowserSearch',
|
||||
'BrowserStop': 'BrowserStop',
|
||||
'Eject': 'Eject',
|
||||
'LaunchApp1': 'LaunchMyComputer',
|
||||
'LaunchApp2': 'LaunchCalendar',
|
||||
'LaunchMail': 'LaunchMail',
|
||||
'MediaPlayPause': 'MediaPlay',
|
||||
'MediaStop': 'MediaStop',
|
||||
'MediaTrackNext': 'MediaTrackNext',
|
||||
'MediaTrackPrevious': 'MediaTrackPrevious',
|
||||
'Power': 'Power',
|
||||
'Sleep': 'Sleep',
|
||||
'AudioVolumeDown': 'AudioVolumeDown',
|
||||
'AudioVolumeMute': 'AudioVolumeMute',
|
||||
'AudioVolumeUp': 'AudioVolumeUp',
|
||||
'WakeUp': 'WakeUp',
|
||||
};
|
370
public/novnc/core/input/keyboard.js
Normal file
@ -0,0 +1,370 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
import * as Log from '../util/logging.js';
|
||||
import { stopEvent } from '../util/events.js';
|
||||
import * as KeyboardUtil from "./util.js";
|
||||
import KeyTable from "./keysym.js";
|
||||
import * as browser from "../util/browser.js";
|
||||
|
||||
//
|
||||
// Keyboard event handler
|
||||
//
|
||||
|
||||
export default class Keyboard {
|
||||
constructor(target) {
|
||||
this._target = target || null;
|
||||
|
||||
this._keyDownList = {}; // List of depressed keys
|
||||
// (even if they are happy)
|
||||
this._pendingKey = null; // Key waiting for keypress
|
||||
this._altGrArmed = false; // Windows AltGr detection
|
||||
|
||||
// keep these here so we can refer to them later
|
||||
this._eventHandlers = {
|
||||
'keyup': this._handleKeyUp.bind(this),
|
||||
'keydown': this._handleKeyDown.bind(this),
|
||||
'keypress': this._handleKeyPress.bind(this),
|
||||
'blur': this._allKeysUp.bind(this),
|
||||
'checkalt': this._checkAlt.bind(this),
|
||||
};
|
||||
|
||||
// ===== EVENT HANDLERS =====
|
||||
|
||||
this.onkeyevent = () => {}; // Handler for key press/release
|
||||
}
|
||||
|
||||
// ===== PRIVATE METHODS =====
|
||||
|
||||
_sendKeyEvent(keysym, code, down) {
|
||||
if (down) {
|
||||
this._keyDownList[code] = keysym;
|
||||
} else {
|
||||
// Do we really think this key is down?
|
||||
if (!(code in this._keyDownList)) {
|
||||
return;
|
||||
}
|
||||
delete this._keyDownList[code];
|
||||
}
|
||||
|
||||
Log.Debug("onkeyevent " + (down ? "down" : "up") +
|
||||
", keysym: " + keysym, ", code: " + code);
|
||||
this.onkeyevent(keysym, code, down);
|
||||
}
|
||||
|
||||
_getKeyCode(e) {
|
||||
const code = KeyboardUtil.getKeycode(e);
|
||||
if (code !== 'Unidentified') {
|
||||
return code;
|
||||
}
|
||||
|
||||
// Unstable, but we don't have anything else to go on
|
||||
// (don't use it for 'keypress' events thought since
|
||||
// WebKit sets it to the same as charCode)
|
||||
if (e.keyCode && (e.type !== 'keypress')) {
|
||||
// 229 is used for composition events
|
||||
if (e.keyCode !== 229) {
|
||||
return 'Platform' + e.keyCode;
|
||||
}
|
||||
}
|
||||
|
||||
// A precursor to the final DOM3 standard. Unfortunately it
|
||||
// is not layout independent, so it is as bad as using keyCode
|
||||
if (e.keyIdentifier) {
|
||||
// Non-character key?
|
||||
if (e.keyIdentifier.substr(0, 2) !== 'U+') {
|
||||
return e.keyIdentifier;
|
||||
}
|
||||
|
||||
const codepoint = parseInt(e.keyIdentifier.substr(2), 16);
|
||||
const char = String.fromCharCode(codepoint).toUpperCase();
|
||||
|
||||
return 'Platform' + char.charCodeAt();
|
||||
}
|
||||
|
||||
return 'Unidentified';
|
||||
}
|
||||
|
||||
_handleKeyDown(e) {
|
||||
const code = this._getKeyCode(e);
|
||||
let keysym = KeyboardUtil.getKeysym(e);
|
||||
|
||||
// Windows doesn't have a proper AltGr, but handles it using
|
||||
// fake Ctrl+Alt. However the remote end might not be Windows,
|
||||
// so we need to merge those in to a single AltGr event. We
|
||||
// detect this case by seeing the two key events directly after
|
||||
// each other with a very short time between them (<50ms).
|
||||
if (this._altGrArmed) {
|
||||
this._altGrArmed = false;
|
||||
clearTimeout(this._altGrTimeout);
|
||||
|
||||
if ((code === "AltRight") &&
|
||||
((e.timeStamp - this._altGrCtrlTime) < 50)) {
|
||||
// FIXME: We fail to detect this if either Ctrl key is
|
||||
// first manually pressed as Windows then no
|
||||
// longer sends the fake Ctrl down event. It
|
||||
// does however happily send real Ctrl events
|
||||
// even when AltGr is already down. Some
|
||||
// browsers detect this for us though and set the
|
||||
// key to "AltGraph".
|
||||
keysym = KeyTable.XK_ISO_Level3_Shift;
|
||||
} else {
|
||||
this._sendKeyEvent(KeyTable.XK_Control_L, "ControlLeft", true);
|
||||
}
|
||||
}
|
||||
|
||||
// We cannot handle keys we cannot track, but we also need
|
||||
// to deal with virtual keyboards which omit key info
|
||||
// (iOS omits tracking info on keyup events, which forces us to
|
||||
// special treat that platform here)
|
||||
if ((code === 'Unidentified') || browser.isIOS()) {
|
||||
if (keysym) {
|
||||
// If it's a virtual keyboard then it should be
|
||||
// sufficient to just send press and release right
|
||||
// after each other
|
||||
this._sendKeyEvent(keysym, code, true);
|
||||
this._sendKeyEvent(keysym, code, false);
|
||||
}
|
||||
|
||||
stopEvent(e);
|
||||
return;
|
||||
}
|
||||
|
||||
// Alt behaves more like AltGraph on macOS, so shuffle the
|
||||
// keys around a bit to make things more sane for the remote
|
||||
// server. This method is used by RealVNC and TigerVNC (and
|
||||
// possibly others).
|
||||
if (browser.isMac()) {
|
||||
switch (keysym) {
|
||||
case KeyTable.XK_Super_L:
|
||||
keysym = KeyTable.XK_Alt_L;
|
||||
break;
|
||||
case KeyTable.XK_Super_R:
|
||||
keysym = KeyTable.XK_Super_L;
|
||||
break;
|
||||
case KeyTable.XK_Alt_L:
|
||||
keysym = KeyTable.XK_Mode_switch;
|
||||
break;
|
||||
case KeyTable.XK_Alt_R:
|
||||
keysym = KeyTable.XK_ISO_Level3_Shift;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Is this key already pressed? If so, then we must use the
|
||||
// same keysym or we'll confuse the server
|
||||
if (code in this._keyDownList) {
|
||||
keysym = this._keyDownList[code];
|
||||
}
|
||||
|
||||
// macOS doesn't send proper key events for modifiers, only
|
||||
// state change events. That gets extra confusing for CapsLock
|
||||
// which toggles on each press, but not on release. So pretend
|
||||
// it was a quick press and release of the button.
|
||||
if (browser.isMac() && (code === 'CapsLock')) {
|
||||
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', true);
|
||||
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', false);
|
||||
stopEvent(e);
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is a legacy browser then we'll need to wait for
|
||||
// a keypress event as well
|
||||
// (IE and Edge has a broken KeyboardEvent.key, so we can't
|
||||
// just check for the presence of that field)
|
||||
if (!keysym && (!e.key || browser.isIE() || browser.isEdge())) {
|
||||
this._pendingKey = code;
|
||||
// However we might not get a keypress event if the key
|
||||
// is non-printable, which needs some special fallback
|
||||
// handling
|
||||
setTimeout(this._handleKeyPressTimeout.bind(this), 10, e);
|
||||
return;
|
||||
}
|
||||
|
||||
this._pendingKey = null;
|
||||
stopEvent(e);
|
||||
|
||||
// Possible start of AltGr sequence? (see above)
|
||||
if ((code === "ControlLeft") && browser.isWindows() &&
|
||||
!("ControlLeft" in this._keyDownList)) {
|
||||
this._altGrArmed = true;
|
||||
this._altGrTimeout = setTimeout(this._handleAltGrTimeout.bind(this), 100);
|
||||
this._altGrCtrlTime = e.timeStamp;
|
||||
return;
|
||||
}
|
||||
|
||||
this._sendKeyEvent(keysym, code, true);
|
||||
}
|
||||
|
||||
// Legacy event for browsers without code/key
|
||||
_handleKeyPress(e) {
|
||||
stopEvent(e);
|
||||
|
||||
// Are we expecting a keypress?
|
||||
if (this._pendingKey === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
let code = this._getKeyCode(e);
|
||||
const keysym = KeyboardUtil.getKeysym(e);
|
||||
|
||||
// The key we were waiting for?
|
||||
if ((code !== 'Unidentified') && (code != this._pendingKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
code = this._pendingKey;
|
||||
this._pendingKey = null;
|
||||
|
||||
if (!keysym) {
|
||||
Log.Info('keypress with no keysym:', e);
|
||||
return;
|
||||
}
|
||||
|
||||
this._sendKeyEvent(keysym, code, true);
|
||||
}
|
||||
|
||||
_handleKeyPressTimeout(e) {
|
||||
// Did someone manage to sort out the key already?
|
||||
if (this._pendingKey === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
let keysym;
|
||||
|
||||
const code = this._pendingKey;
|
||||
this._pendingKey = null;
|
||||
|
||||
// We have no way of knowing the proper keysym with the
|
||||
// information given, but the following are true for most
|
||||
// layouts
|
||||
if ((e.keyCode >= 0x30) && (e.keyCode <= 0x39)) {
|
||||
// Digit
|
||||
keysym = e.keyCode;
|
||||
} else if ((e.keyCode >= 0x41) && (e.keyCode <= 0x5a)) {
|
||||
// Character (A-Z)
|
||||
let char = String.fromCharCode(e.keyCode);
|
||||
// A feeble attempt at the correct case
|
||||
if (e.shiftKey) {
|
||||
char = char.toUpperCase();
|
||||
} else {
|
||||
char = char.toLowerCase();
|
||||
}
|
||||
keysym = char.charCodeAt();
|
||||
} else {
|
||||
// Unknown, give up
|
||||
keysym = 0;
|
||||
}
|
||||
|
||||
this._sendKeyEvent(keysym, code, true);
|
||||
}
|
||||
|
||||
_handleKeyUp(e) {
|
||||
stopEvent(e);
|
||||
|
||||
const code = this._getKeyCode(e);
|
||||
|
||||
// We can't get a release in the middle of an AltGr sequence, so
|
||||
// abort that detection
|
||||
if (this._altGrArmed) {
|
||||
this._altGrArmed = false;
|
||||
clearTimeout(this._altGrTimeout);
|
||||
this._sendKeyEvent(KeyTable.XK_Control_L, "ControlLeft", true);
|
||||
}
|
||||
|
||||
// See comment in _handleKeyDown()
|
||||
if (browser.isMac() && (code === 'CapsLock')) {
|
||||
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', true);
|
||||
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', false);
|
||||
return;
|
||||
}
|
||||
|
||||
this._sendKeyEvent(this._keyDownList[code], code, false);
|
||||
}
|
||||
|
||||
_handleAltGrTimeout() {
|
||||
this._altGrArmed = false;
|
||||
clearTimeout(this._altGrTimeout);
|
||||
this._sendKeyEvent(KeyTable.XK_Control_L, "ControlLeft", true);
|
||||
}
|
||||
|
||||
_allKeysUp() {
|
||||
Log.Debug(">> Keyboard.allKeysUp");
|
||||
for (let code in this._keyDownList) {
|
||||
this._sendKeyEvent(this._keyDownList[code], code, false);
|
||||
}
|
||||
Log.Debug("<< Keyboard.allKeysUp");
|
||||
}
|
||||
|
||||
// Firefox Alt workaround, see below
|
||||
_checkAlt(e) {
|
||||
if (e.altKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
const target = this._target;
|
||||
const downList = this._keyDownList;
|
||||
['AltLeft', 'AltRight'].forEach((code) => {
|
||||
if (!(code in downList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const event = new KeyboardEvent('keyup',
|
||||
{ key: downList[code],
|
||||
code: code });
|
||||
target.dispatchEvent(event);
|
||||
});
|
||||
}
|
||||
|
||||
// ===== PUBLIC METHODS =====
|
||||
|
||||
grab() {
|
||||
//Log.Debug(">> Keyboard.grab");
|
||||
|
||||
this._target.addEventListener('keydown', this._eventHandlers.keydown);
|
||||
this._target.addEventListener('keyup', this._eventHandlers.keyup);
|
||||
this._target.addEventListener('keypress', this._eventHandlers.keypress);
|
||||
|
||||
// Release (key up) if window loses focus
|
||||
window.addEventListener('blur', this._eventHandlers.blur);
|
||||
|
||||
// Firefox has broken handling of Alt, so we need to poll as
|
||||
// best we can for releases (still doesn't prevent the menu
|
||||
// from popping up though as we can't call preventDefault())
|
||||
if (browser.isWindows() && browser.isFirefox()) {
|
||||
const handler = this._eventHandlers.checkalt;
|
||||
['mousedown', 'mouseup', 'mousemove', 'wheel',
|
||||
'touchstart', 'touchend', 'touchmove',
|
||||
'keydown', 'keyup'].forEach(type =>
|
||||
document.addEventListener(type, handler,
|
||||
{ capture: true,
|
||||
passive: true }));
|
||||
}
|
||||
|
||||
//Log.Debug("<< Keyboard.grab");
|
||||
}
|
||||
|
||||
ungrab() {
|
||||
//Log.Debug(">> Keyboard.ungrab");
|
||||
|
||||
if (browser.isWindows() && browser.isFirefox()) {
|
||||
const handler = this._eventHandlers.checkalt;
|
||||
['mousedown', 'mouseup', 'mousemove', 'wheel',
|
||||
'touchstart', 'touchend', 'touchmove',
|
||||
'keydown', 'keyup'].forEach(type => document.removeEventListener(type, handler));
|
||||
}
|
||||
|
||||
this._target.removeEventListener('keydown', this._eventHandlers.keydown);
|
||||
this._target.removeEventListener('keyup', this._eventHandlers.keyup);
|
||||
this._target.removeEventListener('keypress', this._eventHandlers.keypress);
|
||||
window.removeEventListener('blur', this._eventHandlers.blur);
|
||||
|
||||
// Release (key up) all keys that are in a down state
|
||||
this._allKeysUp();
|
||||
|
||||
//Log.Debug(">> Keyboard.ungrab");
|
||||
}
|
||||
}
|
616
public/novnc/core/input/keysym.js
Normal file
@ -0,0 +1,616 @@
|
||||
/* eslint-disable key-spacing */
|
||||
|
||||
export default {
|
||||
XK_VoidSymbol: 0xffffff, /* Void symbol */
|
||||
|
||||
XK_BackSpace: 0xff08, /* Back space, back char */
|
||||
XK_Tab: 0xff09,
|
||||
XK_Linefeed: 0xff0a, /* Linefeed, LF */
|
||||
XK_Clear: 0xff0b,
|
||||
XK_Return: 0xff0d, /* Return, enter */
|
||||
XK_Pause: 0xff13, /* Pause, hold */
|
||||
XK_Scroll_Lock: 0xff14,
|
||||
XK_Sys_Req: 0xff15,
|
||||
XK_Escape: 0xff1b,
|
||||
XK_Delete: 0xffff, /* Delete, rubout */
|
||||
|
||||
/* International & multi-key character composition */
|
||||
|
||||
XK_Multi_key: 0xff20, /* Multi-key character compose */
|
||||
XK_Codeinput: 0xff37,
|
||||
XK_SingleCandidate: 0xff3c,
|
||||
XK_MultipleCandidate: 0xff3d,
|
||||
XK_PreviousCandidate: 0xff3e,
|
||||
|
||||
/* Japanese keyboard support */
|
||||
|
||||
XK_Kanji: 0xff21, /* Kanji, Kanji convert */
|
||||
XK_Muhenkan: 0xff22, /* Cancel Conversion */
|
||||
XK_Henkan_Mode: 0xff23, /* Start/Stop Conversion */
|
||||
XK_Henkan: 0xff23, /* Alias for Henkan_Mode */
|
||||
XK_Romaji: 0xff24, /* to Romaji */
|
||||
XK_Hiragana: 0xff25, /* to Hiragana */
|
||||
XK_Katakana: 0xff26, /* to Katakana */
|
||||
XK_Hiragana_Katakana: 0xff27, /* Hiragana/Katakana toggle */
|
||||
XK_Zenkaku: 0xff28, /* to Zenkaku */
|
||||
XK_Hankaku: 0xff29, /* to Hankaku */
|
||||
XK_Zenkaku_Hankaku: 0xff2a, /* Zenkaku/Hankaku toggle */
|
||||
XK_Touroku: 0xff2b, /* Add to Dictionary */
|
||||
XK_Massyo: 0xff2c, /* Delete from Dictionary */
|
||||
XK_Kana_Lock: 0xff2d, /* Kana Lock */
|
||||
XK_Kana_Shift: 0xff2e, /* Kana Shift */
|
||||
XK_Eisu_Shift: 0xff2f, /* Alphanumeric Shift */
|
||||
XK_Eisu_toggle: 0xff30, /* Alphanumeric toggle */
|
||||
XK_Kanji_Bangou: 0xff37, /* Codeinput */
|
||||
XK_Zen_Koho: 0xff3d, /* Multiple/All Candidate(s) */
|
||||
XK_Mae_Koho: 0xff3e, /* Previous Candidate */
|
||||
|
||||
/* Cursor control & motion */
|
||||
|
||||
XK_Home: 0xff50,
|
||||
XK_Left: 0xff51, /* Move left, left arrow */
|
||||
XK_Up: 0xff52, /* Move up, up arrow */
|
||||
XK_Right: 0xff53, /* Move right, right arrow */
|
||||
XK_Down: 0xff54, /* Move down, down arrow */
|
||||
XK_Prior: 0xff55, /* Prior, previous */
|
||||
XK_Page_Up: 0xff55,
|
||||
XK_Next: 0xff56, /* Next */
|
||||
XK_Page_Down: 0xff56,
|
||||
XK_End: 0xff57, /* EOL */
|
||||
XK_Begin: 0xff58, /* BOL */
|
||||
|
||||
|
||||
/* Misc functions */
|
||||
|
||||
XK_Select: 0xff60, /* Select, mark */
|
||||
XK_Print: 0xff61,
|
||||
XK_Execute: 0xff62, /* Execute, run, do */
|
||||
XK_Insert: 0xff63, /* Insert, insert here */
|
||||
XK_Undo: 0xff65,
|
||||
XK_Redo: 0xff66, /* Redo, again */
|
||||
XK_Menu: 0xff67,
|
||||
XK_Find: 0xff68, /* Find, search */
|
||||
XK_Cancel: 0xff69, /* Cancel, stop, abort, exit */
|
||||
XK_Help: 0xff6a, /* Help */
|
||||
XK_Break: 0xff6b,
|
||||
XK_Mode_switch: 0xff7e, /* Character set switch */
|
||||
XK_script_switch: 0xff7e, /* Alias for mode_switch */
|
||||
XK_Num_Lock: 0xff7f,
|
||||
|
||||
/* Keypad functions, keypad numbers cleverly chosen to map to ASCII */
|
||||
|
||||
XK_KP_Space: 0xff80, /* Space */
|
||||
XK_KP_Tab: 0xff89,
|
||||
XK_KP_Enter: 0xff8d, /* Enter */
|
||||
XK_KP_F1: 0xff91, /* PF1, KP_A, ... */
|
||||
XK_KP_F2: 0xff92,
|
||||
XK_KP_F3: 0xff93,
|
||||
XK_KP_F4: 0xff94,
|
||||
XK_KP_Home: 0xff95,
|
||||
XK_KP_Left: 0xff96,
|
||||
XK_KP_Up: 0xff97,
|
||||
XK_KP_Right: 0xff98,
|
||||
XK_KP_Down: 0xff99,
|
||||
XK_KP_Prior: 0xff9a,
|
||||
XK_KP_Page_Up: 0xff9a,
|
||||
XK_KP_Next: 0xff9b,
|
||||
XK_KP_Page_Down: 0xff9b,
|
||||
XK_KP_End: 0xff9c,
|
||||
XK_KP_Begin: 0xff9d,
|
||||
XK_KP_Insert: 0xff9e,
|
||||
XK_KP_Delete: 0xff9f,
|
||||
XK_KP_Equal: 0xffbd, /* Equals */
|
||||
XK_KP_Multiply: 0xffaa,
|
||||
XK_KP_Add: 0xffab,
|
||||
XK_KP_Separator: 0xffac, /* Separator, often comma */
|
||||
XK_KP_Subtract: 0xffad,
|
||||
XK_KP_Decimal: 0xffae,
|
||||
XK_KP_Divide: 0xffaf,
|
||||
|
||||
XK_KP_0: 0xffb0,
|
||||
XK_KP_1: 0xffb1,
|
||||
XK_KP_2: 0xffb2,
|
||||
XK_KP_3: 0xffb3,
|
||||
XK_KP_4: 0xffb4,
|
||||
XK_KP_5: 0xffb5,
|
||||
XK_KP_6: 0xffb6,
|
||||
XK_KP_7: 0xffb7,
|
||||
XK_KP_8: 0xffb8,
|
||||
XK_KP_9: 0xffb9,
|
||||
|
||||
/*
|
||||
* Auxiliary functions; note the duplicate definitions for left and right
|
||||
* function keys; Sun keyboards and a few other manufacturers have such
|
||||
* function key groups on the left and/or right sides of the keyboard.
|
||||
* We've not found a keyboard with more than 35 function keys total.
|
||||
*/
|
||||
|
||||
XK_F1: 0xffbe,
|
||||
XK_F2: 0xffbf,
|
||||
XK_F3: 0xffc0,
|
||||
XK_F4: 0xffc1,
|
||||
XK_F5: 0xffc2,
|
||||
XK_F6: 0xffc3,
|
||||
XK_F7: 0xffc4,
|
||||
XK_F8: 0xffc5,
|
||||
XK_F9: 0xffc6,
|
||||
XK_F10: 0xffc7,
|
||||
XK_F11: 0xffc8,
|
||||
XK_L1: 0xffc8,
|
||||
XK_F12: 0xffc9,
|
||||
XK_L2: 0xffc9,
|
||||
XK_F13: 0xffca,
|
||||
XK_L3: 0xffca,
|
||||
XK_F14: 0xffcb,
|
||||
XK_L4: 0xffcb,
|
||||
XK_F15: 0xffcc,
|
||||
XK_L5: 0xffcc,
|
||||
XK_F16: 0xffcd,
|
||||
XK_L6: 0xffcd,
|
||||
XK_F17: 0xffce,
|
||||
XK_L7: 0xffce,
|
||||
XK_F18: 0xffcf,
|
||||
XK_L8: 0xffcf,
|
||||
XK_F19: 0xffd0,
|
||||
XK_L9: 0xffd0,
|
||||
XK_F20: 0xffd1,
|
||||
XK_L10: 0xffd1,
|
||||
XK_F21: 0xffd2,
|
||||
XK_R1: 0xffd2,
|
||||
XK_F22: 0xffd3,
|
||||
XK_R2: 0xffd3,
|
||||
XK_F23: 0xffd4,
|
||||
XK_R3: 0xffd4,
|
||||
XK_F24: 0xffd5,
|
||||
XK_R4: 0xffd5,
|
||||
XK_F25: 0xffd6,
|
||||
XK_R5: 0xffd6,
|
||||
XK_F26: 0xffd7,
|
||||
XK_R6: 0xffd7,
|
||||
XK_F27: 0xffd8,
|
||||
XK_R7: 0xffd8,
|
||||
XK_F28: 0xffd9,
|
||||
XK_R8: 0xffd9,
|
||||
XK_F29: 0xffda,
|
||||
XK_R9: 0xffda,
|
||||
XK_F30: 0xffdb,
|
||||
XK_R10: 0xffdb,
|
||||
XK_F31: 0xffdc,
|
||||
XK_R11: 0xffdc,
|
||||
XK_F32: 0xffdd,
|
||||
XK_R12: 0xffdd,
|
||||
XK_F33: 0xffde,
|
||||
XK_R13: 0xffde,
|
||||
XK_F34: 0xffdf,
|
||||
XK_R14: 0xffdf,
|
||||
XK_F35: 0xffe0,
|
||||
XK_R15: 0xffe0,
|
||||
|
||||
/* Modifiers */
|
||||
|
||||
XK_Shift_L: 0xffe1, /* Left shift */
|
||||
XK_Shift_R: 0xffe2, /* Right shift */
|
||||
XK_Control_L: 0xffe3, /* Left control */
|
||||
XK_Control_R: 0xffe4, /* Right control */
|
||||
XK_Caps_Lock: 0xffe5, /* Caps lock */
|
||||
XK_Shift_Lock: 0xffe6, /* Shift lock */
|
||||
|
||||
XK_Meta_L: 0xffe7, /* Left meta */
|
||||
XK_Meta_R: 0xffe8, /* Right meta */
|
||||
XK_Alt_L: 0xffe9, /* Left alt */
|
||||
XK_Alt_R: 0xffea, /* Right alt */
|
||||
XK_Super_L: 0xffeb, /* Left super */
|
||||
XK_Super_R: 0xffec, /* Right super */
|
||||
XK_Hyper_L: 0xffed, /* Left hyper */
|
||||
XK_Hyper_R: 0xffee, /* Right hyper */
|
||||
|
||||
/*
|
||||
* Keyboard (XKB) Extension function and modifier keys
|
||||
* (from Appendix C of "The X Keyboard Extension: Protocol Specification")
|
||||
* Byte 3 = 0xfe
|
||||
*/
|
||||
|
||||
XK_ISO_Level3_Shift: 0xfe03, /* AltGr */
|
||||
XK_ISO_Next_Group: 0xfe08,
|
||||
XK_ISO_Prev_Group: 0xfe0a,
|
||||
XK_ISO_First_Group: 0xfe0c,
|
||||
XK_ISO_Last_Group: 0xfe0e,
|
||||
|
||||
/*
|
||||
* Latin 1
|
||||
* (ISO/IEC 8859-1: Unicode U+0020..U+00FF)
|
||||
* Byte 3: 0
|
||||
*/
|
||||
|
||||
XK_space: 0x0020, /* U+0020 SPACE */
|
||||
XK_exclam: 0x0021, /* U+0021 EXCLAMATION MARK */
|
||||
XK_quotedbl: 0x0022, /* U+0022 QUOTATION MARK */
|
||||
XK_numbersign: 0x0023, /* U+0023 NUMBER SIGN */
|
||||
XK_dollar: 0x0024, /* U+0024 DOLLAR SIGN */
|
||||
XK_percent: 0x0025, /* U+0025 PERCENT SIGN */
|
||||
XK_ampersand: 0x0026, /* U+0026 AMPERSAND */
|
||||
XK_apostrophe: 0x0027, /* U+0027 APOSTROPHE */
|
||||
XK_quoteright: 0x0027, /* deprecated */
|
||||
XK_parenleft: 0x0028, /* U+0028 LEFT PARENTHESIS */
|
||||
XK_parenright: 0x0029, /* U+0029 RIGHT PARENTHESIS */
|
||||
XK_asterisk: 0x002a, /* U+002A ASTERISK */
|
||||
XK_plus: 0x002b, /* U+002B PLUS SIGN */
|
||||
XK_comma: 0x002c, /* U+002C COMMA */
|
||||
XK_minus: 0x002d, /* U+002D HYPHEN-MINUS */
|
||||
XK_period: 0x002e, /* U+002E FULL STOP */
|
||||
XK_slash: 0x002f, /* U+002F SOLIDUS */
|
||||
XK_0: 0x0030, /* U+0030 DIGIT ZERO */
|
||||
XK_1: 0x0031, /* U+0031 DIGIT ONE */
|
||||
XK_2: 0x0032, /* U+0032 DIGIT TWO */
|
||||
XK_3: 0x0033, /* U+0033 DIGIT THREE */
|
||||
XK_4: 0x0034, /* U+0034 DIGIT FOUR */
|
||||
XK_5: 0x0035, /* U+0035 DIGIT FIVE */
|
||||
XK_6: 0x0036, /* U+0036 DIGIT SIX */
|
||||
XK_7: 0x0037, /* U+0037 DIGIT SEVEN */
|
||||
XK_8: 0x0038, /* U+0038 DIGIT EIGHT */
|
||||
XK_9: 0x0039, /* U+0039 DIGIT NINE */
|
||||
XK_colon: 0x003a, /* U+003A COLON */
|
||||
XK_semicolon: 0x003b, /* U+003B SEMICOLON */
|
||||
XK_less: 0x003c, /* U+003C LESS-THAN SIGN */
|
||||
XK_equal: 0x003d, /* U+003D EQUALS SIGN */
|
||||
XK_greater: 0x003e, /* U+003E GREATER-THAN SIGN */
|
||||
XK_question: 0x003f, /* U+003F QUESTION MARK */
|
||||
XK_at: 0x0040, /* U+0040 COMMERCIAL AT */
|
||||
XK_A: 0x0041, /* U+0041 LATIN CAPITAL LETTER A */
|
||||
XK_B: 0x0042, /* U+0042 LATIN CAPITAL LETTER B */
|
||||
XK_C: 0x0043, /* U+0043 LATIN CAPITAL LETTER C */
|
||||
XK_D: 0x0044, /* U+0044 LATIN CAPITAL LETTER D */
|
||||
XK_E: 0x0045, /* U+0045 LATIN CAPITAL LETTER E */
|
||||
XK_F: 0x0046, /* U+0046 LATIN CAPITAL LETTER F */
|
||||
XK_G: 0x0047, /* U+0047 LATIN CAPITAL LETTER G */
|
||||
XK_H: 0x0048, /* U+0048 LATIN CAPITAL LETTER H */
|
||||
XK_I: 0x0049, /* U+0049 LATIN CAPITAL LETTER I */
|
||||
XK_J: 0x004a, /* U+004A LATIN CAPITAL LETTER J */
|
||||
XK_K: 0x004b, /* U+004B LATIN CAPITAL LETTER K */
|
||||
XK_L: 0x004c, /* U+004C LATIN CAPITAL LETTER L */
|
||||
XK_M: 0x004d, /* U+004D LATIN CAPITAL LETTER M */
|
||||
XK_N: 0x004e, /* U+004E LATIN CAPITAL LETTER N */
|
||||
XK_O: 0x004f, /* U+004F LATIN CAPITAL LETTER O */
|
||||
XK_P: 0x0050, /* U+0050 LATIN CAPITAL LETTER P */
|
||||
XK_Q: 0x0051, /* U+0051 LATIN CAPITAL LETTER Q */
|
||||
XK_R: 0x0052, /* U+0052 LATIN CAPITAL LETTER R */
|
||||
XK_S: 0x0053, /* U+0053 LATIN CAPITAL LETTER S */
|
||||
XK_T: 0x0054, /* U+0054 LATIN CAPITAL LETTER T */
|
||||
XK_U: 0x0055, /* U+0055 LATIN CAPITAL LETTER U */
|
||||
XK_V: 0x0056, /* U+0056 LATIN CAPITAL LETTER V */
|
||||
XK_W: 0x0057, /* U+0057 LATIN CAPITAL LETTER W */
|
||||
XK_X: 0x0058, /* U+0058 LATIN CAPITAL LETTER X */
|
||||
XK_Y: 0x0059, /* U+0059 LATIN CAPITAL LETTER Y */
|
||||
XK_Z: 0x005a, /* U+005A LATIN CAPITAL LETTER Z */
|
||||
XK_bracketleft: 0x005b, /* U+005B LEFT SQUARE BRACKET */
|
||||
XK_backslash: 0x005c, /* U+005C REVERSE SOLIDUS */
|
||||
XK_bracketright: 0x005d, /* U+005D RIGHT SQUARE BRACKET */
|
||||
XK_asciicircum: 0x005e, /* U+005E CIRCUMFLEX ACCENT */
|
||||
XK_underscore: 0x005f, /* U+005F LOW LINE */
|
||||
XK_grave: 0x0060, /* U+0060 GRAVE ACCENT */
|
||||
XK_quoteleft: 0x0060, /* deprecated */
|
||||
XK_a: 0x0061, /* U+0061 LATIN SMALL LETTER A */
|
||||
XK_b: 0x0062, /* U+0062 LATIN SMALL LETTER B */
|
||||
XK_c: 0x0063, /* U+0063 LATIN SMALL LETTER C */
|
||||
XK_d: 0x0064, /* U+0064 LATIN SMALL LETTER D */
|
||||
XK_e: 0x0065, /* U+0065 LATIN SMALL LETTER E */
|
||||
XK_f: 0x0066, /* U+0066 LATIN SMALL LETTER F */
|
||||
XK_g: 0x0067, /* U+0067 LATIN SMALL LETTER G */
|
||||
XK_h: 0x0068, /* U+0068 LATIN SMALL LETTER H */
|
||||
XK_i: 0x0069, /* U+0069 LATIN SMALL LETTER I */
|
||||
XK_j: 0x006a, /* U+006A LATIN SMALL LETTER J */
|
||||
XK_k: 0x006b, /* U+006B LATIN SMALL LETTER K */
|
||||
XK_l: 0x006c, /* U+006C LATIN SMALL LETTER L */
|
||||
XK_m: 0x006d, /* U+006D LATIN SMALL LETTER M */
|
||||
XK_n: 0x006e, /* U+006E LATIN SMALL LETTER N */
|
||||
XK_o: 0x006f, /* U+006F LATIN SMALL LETTER O */
|
||||
XK_p: 0x0070, /* U+0070 LATIN SMALL LETTER P */
|
||||
XK_q: 0x0071, /* U+0071 LATIN SMALL LETTER Q */
|
||||
XK_r: 0x0072, /* U+0072 LATIN SMALL LETTER R */
|
||||
XK_s: 0x0073, /* U+0073 LATIN SMALL LETTER S */
|
||||
XK_t: 0x0074, /* U+0074 LATIN SMALL LETTER T */
|
||||
XK_u: 0x0075, /* U+0075 LATIN SMALL LETTER U */
|
||||
XK_v: 0x0076, /* U+0076 LATIN SMALL LETTER V */
|
||||
XK_w: 0x0077, /* U+0077 LATIN SMALL LETTER W */
|
||||
XK_x: 0x0078, /* U+0078 LATIN SMALL LETTER X */
|
||||
XK_y: 0x0079, /* U+0079 LATIN SMALL LETTER Y */
|
||||
XK_z: 0x007a, /* U+007A LATIN SMALL LETTER Z */
|
||||
XK_braceleft: 0x007b, /* U+007B LEFT CURLY BRACKET */
|
||||
XK_bar: 0x007c, /* U+007C VERTICAL LINE */
|
||||
XK_braceright: 0x007d, /* U+007D RIGHT CURLY BRACKET */
|
||||
XK_asciitilde: 0x007e, /* U+007E TILDE */
|
||||
|
||||
XK_nobreakspace: 0x00a0, /* U+00A0 NO-BREAK SPACE */
|
||||
XK_exclamdown: 0x00a1, /* U+00A1 INVERTED EXCLAMATION MARK */
|
||||
XK_cent: 0x00a2, /* U+00A2 CENT SIGN */
|
||||
XK_sterling: 0x00a3, /* U+00A3 POUND SIGN */
|
||||
XK_currency: 0x00a4, /* U+00A4 CURRENCY SIGN */
|
||||
XK_yen: 0x00a5, /* U+00A5 YEN SIGN */
|
||||
XK_brokenbar: 0x00a6, /* U+00A6 BROKEN BAR */
|
||||
XK_section: 0x00a7, /* U+00A7 SECTION SIGN */
|
||||
XK_diaeresis: 0x00a8, /* U+00A8 DIAERESIS */
|
||||
XK_copyright: 0x00a9, /* U+00A9 COPYRIGHT SIGN */
|
||||
XK_ordfeminine: 0x00aa, /* U+00AA FEMININE ORDINAL INDICATOR */
|
||||
XK_guillemotleft: 0x00ab, /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
|
||||
XK_notsign: 0x00ac, /* U+00AC NOT SIGN */
|
||||
XK_hyphen: 0x00ad, /* U+00AD SOFT HYPHEN */
|
||||
XK_registered: 0x00ae, /* U+00AE REGISTERED SIGN */
|
||||
XK_macron: 0x00af, /* U+00AF MACRON */
|
||||
XK_degree: 0x00b0, /* U+00B0 DEGREE SIGN */
|
||||
XK_plusminus: 0x00b1, /* U+00B1 PLUS-MINUS SIGN */
|
||||
XK_twosuperior: 0x00b2, /* U+00B2 SUPERSCRIPT TWO */
|
||||
XK_threesuperior: 0x00b3, /* U+00B3 SUPERSCRIPT THREE */
|
||||
XK_acute: 0x00b4, /* U+00B4 ACUTE ACCENT */
|
||||
XK_mu: 0x00b5, /* U+00B5 MICRO SIGN */
|
||||
XK_paragraph: 0x00b6, /* U+00B6 PILCROW SIGN */
|
||||
XK_periodcentered: 0x00b7, /* U+00B7 MIDDLE DOT */
|
||||
XK_cedilla: 0x00b8, /* U+00B8 CEDILLA */
|
||||
XK_onesuperior: 0x00b9, /* U+00B9 SUPERSCRIPT ONE */
|
||||
XK_masculine: 0x00ba, /* U+00BA MASCULINE ORDINAL INDICATOR */
|
||||
XK_guillemotright: 0x00bb, /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
|
||||
XK_onequarter: 0x00bc, /* U+00BC VULGAR FRACTION ONE QUARTER */
|
||||
XK_onehalf: 0x00bd, /* U+00BD VULGAR FRACTION ONE HALF */
|
||||
XK_threequarters: 0x00be, /* U+00BE VULGAR FRACTION THREE QUARTERS */
|
||||
XK_questiondown: 0x00bf, /* U+00BF INVERTED QUESTION MARK */
|
||||
XK_Agrave: 0x00c0, /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */
|
||||
XK_Aacute: 0x00c1, /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */
|
||||
XK_Acircumflex: 0x00c2, /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
|
||||
XK_Atilde: 0x00c3, /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */
|
||||
XK_Adiaeresis: 0x00c4, /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */
|
||||
XK_Aring: 0x00c5, /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */
|
||||
XK_AE: 0x00c6, /* U+00C6 LATIN CAPITAL LETTER AE */
|
||||
XK_Ccedilla: 0x00c7, /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */
|
||||
XK_Egrave: 0x00c8, /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */
|
||||
XK_Eacute: 0x00c9, /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
|
||||
XK_Ecircumflex: 0x00ca, /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
|
||||
XK_Ediaeresis: 0x00cb, /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */
|
||||
XK_Igrave: 0x00cc, /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */
|
||||
XK_Iacute: 0x00cd, /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */
|
||||
XK_Icircumflex: 0x00ce, /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
|
||||
XK_Idiaeresis: 0x00cf, /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */
|
||||
XK_ETH: 0x00d0, /* U+00D0 LATIN CAPITAL LETTER ETH */
|
||||
XK_Eth: 0x00d0, /* deprecated */
|
||||
XK_Ntilde: 0x00d1, /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */
|
||||
XK_Ograve: 0x00d2, /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */
|
||||
XK_Oacute: 0x00d3, /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */
|
||||
XK_Ocircumflex: 0x00d4, /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
|
||||
XK_Otilde: 0x00d5, /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */
|
||||
XK_Odiaeresis: 0x00d6, /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */
|
||||
XK_multiply: 0x00d7, /* U+00D7 MULTIPLICATION SIGN */
|
||||
XK_Oslash: 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
|
||||
XK_Ooblique: 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
|
||||
XK_Ugrave: 0x00d9, /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */
|
||||
XK_Uacute: 0x00da, /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */
|
||||
XK_Ucircumflex: 0x00db, /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
|
||||
XK_Udiaeresis: 0x00dc, /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */
|
||||
XK_Yacute: 0x00dd, /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */
|
||||
XK_THORN: 0x00de, /* U+00DE LATIN CAPITAL LETTER THORN */
|
||||
XK_Thorn: 0x00de, /* deprecated */
|
||||
XK_ssharp: 0x00df, /* U+00DF LATIN SMALL LETTER SHARP S */
|
||||
XK_agrave: 0x00e0, /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */
|
||||
XK_aacute: 0x00e1, /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */
|
||||
XK_acircumflex: 0x00e2, /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */
|
||||
XK_atilde: 0x00e3, /* U+00E3 LATIN SMALL LETTER A WITH TILDE */
|
||||
XK_adiaeresis: 0x00e4, /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */
|
||||
XK_aring: 0x00e5, /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */
|
||||
XK_ae: 0x00e6, /* U+00E6 LATIN SMALL LETTER AE */
|
||||
XK_ccedilla: 0x00e7, /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */
|
||||
XK_egrave: 0x00e8, /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */
|
||||
XK_eacute: 0x00e9, /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
|
||||
XK_ecircumflex: 0x00ea, /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */
|
||||
XK_ediaeresis: 0x00eb, /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */
|
||||
XK_igrave: 0x00ec, /* U+00EC LATIN SMALL LETTER I WITH GRAVE */
|
||||
XK_iacute: 0x00ed, /* U+00ED LATIN SMALL LETTER I WITH ACUTE */
|
||||
XK_icircumflex: 0x00ee, /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */
|
||||
XK_idiaeresis: 0x00ef, /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */
|
||||
XK_eth: 0x00f0, /* U+00F0 LATIN SMALL LETTER ETH */
|
||||
XK_ntilde: 0x00f1, /* U+00F1 LATIN SMALL LETTER N WITH TILDE */
|
||||
XK_ograve: 0x00f2, /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */
|
||||
XK_oacute: 0x00f3, /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */
|
||||
XK_ocircumflex: 0x00f4, /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */
|
||||
XK_otilde: 0x00f5, /* U+00F5 LATIN SMALL LETTER O WITH TILDE */
|
||||
XK_odiaeresis: 0x00f6, /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */
|
||||
XK_division: 0x00f7, /* U+00F7 DIVISION SIGN */
|
||||
XK_oslash: 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
|
||||
XK_ooblique: 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
|
||||
XK_ugrave: 0x00f9, /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */
|
||||
XK_uacute: 0x00fa, /* U+00FA LATIN SMALL LETTER U WITH ACUTE */
|
||||
XK_ucircumflex: 0x00fb, /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */
|
||||
XK_udiaeresis: 0x00fc, /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */
|
||||
XK_yacute: 0x00fd, /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */
|
||||
XK_thorn: 0x00fe, /* U+00FE LATIN SMALL LETTER THORN */
|
||||
XK_ydiaeresis: 0x00ff, /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
|
||||
|
||||
/*
|
||||
* Korean
|
||||
* Byte 3 = 0x0e
|
||||
*/
|
||||
|
||||
XK_Hangul: 0xff31, /* Hangul start/stop(toggle) */
|
||||
XK_Hangul_Hanja: 0xff34, /* Start Hangul->Hanja Conversion */
|
||||
XK_Hangul_Jeonja: 0xff38, /* Jeonja mode */
|
||||
|
||||
/*
|
||||
* XFree86 vendor specific keysyms.
|
||||
*
|
||||
* The XFree86 keysym range is 0x10080001 - 0x1008FFFF.
|
||||
*/
|
||||
|
||||
XF86XK_ModeLock: 0x1008FF01,
|
||||
XF86XK_MonBrightnessUp: 0x1008FF02,
|
||||
XF86XK_MonBrightnessDown: 0x1008FF03,
|
||||
XF86XK_KbdLightOnOff: 0x1008FF04,
|
||||
XF86XK_KbdBrightnessUp: 0x1008FF05,
|
||||
XF86XK_KbdBrightnessDown: 0x1008FF06,
|
||||
XF86XK_Standby: 0x1008FF10,
|
||||
XF86XK_AudioLowerVolume: 0x1008FF11,
|
||||
XF86XK_AudioMute: 0x1008FF12,
|
||||
XF86XK_AudioRaiseVolume: 0x1008FF13,
|
||||
XF86XK_AudioPlay: 0x1008FF14,
|
||||
XF86XK_AudioStop: 0x1008FF15,
|
||||
XF86XK_AudioPrev: 0x1008FF16,
|
||||
XF86XK_AudioNext: 0x1008FF17,
|
||||
XF86XK_HomePage: 0x1008FF18,
|
||||
XF86XK_Mail: 0x1008FF19,
|
||||
XF86XK_Start: 0x1008FF1A,
|
||||
XF86XK_Search: 0x1008FF1B,
|
||||
XF86XK_AudioRecord: 0x1008FF1C,
|
||||
XF86XK_Calculator: 0x1008FF1D,
|
||||
XF86XK_Memo: 0x1008FF1E,
|
||||
XF86XK_ToDoList: 0x1008FF1F,
|
||||
XF86XK_Calendar: 0x1008FF20,
|
||||
XF86XK_PowerDown: 0x1008FF21,
|
||||
XF86XK_ContrastAdjust: 0x1008FF22,
|
||||
XF86XK_RockerUp: 0x1008FF23,
|
||||
XF86XK_RockerDown: 0x1008FF24,
|
||||
XF86XK_RockerEnter: 0x1008FF25,
|
||||
XF86XK_Back: 0x1008FF26,
|
||||
XF86XK_Forward: 0x1008FF27,
|
||||
XF86XK_Stop: 0x1008FF28,
|
||||
XF86XK_Refresh: 0x1008FF29,
|
||||
XF86XK_PowerOff: 0x1008FF2A,
|
||||
XF86XK_WakeUp: 0x1008FF2B,
|
||||
XF86XK_Eject: 0x1008FF2C,
|
||||
XF86XK_ScreenSaver: 0x1008FF2D,
|
||||
XF86XK_WWW: 0x1008FF2E,
|
||||
XF86XK_Sleep: 0x1008FF2F,
|
||||
XF86XK_Favorites: 0x1008FF30,
|
||||
XF86XK_AudioPause: 0x1008FF31,
|
||||
XF86XK_AudioMedia: 0x1008FF32,
|
||||
XF86XK_MyComputer: 0x1008FF33,
|
||||
XF86XK_VendorHome: 0x1008FF34,
|
||||
XF86XK_LightBulb: 0x1008FF35,
|
||||
XF86XK_Shop: 0x1008FF36,
|
||||
XF86XK_History: 0x1008FF37,
|
||||
XF86XK_OpenURL: 0x1008FF38,
|
||||
XF86XK_AddFavorite: 0x1008FF39,
|
||||
XF86XK_HotLinks: 0x1008FF3A,
|
||||
XF86XK_BrightnessAdjust: 0x1008FF3B,
|
||||
XF86XK_Finance: 0x1008FF3C,
|
||||
XF86XK_Community: 0x1008FF3D,
|
||||
XF86XK_AudioRewind: 0x1008FF3E,
|
||||
XF86XK_BackForward: 0x1008FF3F,
|
||||
XF86XK_Launch0: 0x1008FF40,
|
||||
XF86XK_Launch1: 0x1008FF41,
|
||||
XF86XK_Launch2: 0x1008FF42,
|
||||
XF86XK_Launch3: 0x1008FF43,
|
||||
XF86XK_Launch4: 0x1008FF44,
|
||||
XF86XK_Launch5: 0x1008FF45,
|
||||
XF86XK_Launch6: 0x1008FF46,
|
||||
XF86XK_Launch7: 0x1008FF47,
|
||||
XF86XK_Launch8: 0x1008FF48,
|
||||
XF86XK_Launch9: 0x1008FF49,
|
||||
XF86XK_LaunchA: 0x1008FF4A,
|
||||
XF86XK_LaunchB: 0x1008FF4B,
|
||||
XF86XK_LaunchC: 0x1008FF4C,
|
||||
XF86XK_LaunchD: 0x1008FF4D,
|
||||
XF86XK_LaunchE: 0x1008FF4E,
|
||||
XF86XK_LaunchF: 0x1008FF4F,
|
||||
XF86XK_ApplicationLeft: 0x1008FF50,
|
||||
XF86XK_ApplicationRight: 0x1008FF51,
|
||||
XF86XK_Book: 0x1008FF52,
|
||||
XF86XK_CD: 0x1008FF53,
|
||||
XF86XK_Calculater: 0x1008FF54,
|
||||
XF86XK_Clear: 0x1008FF55,
|
||||
XF86XK_Close: 0x1008FF56,
|
||||
XF86XK_Copy: 0x1008FF57,
|
||||
XF86XK_Cut: 0x1008FF58,
|
||||
XF86XK_Display: 0x1008FF59,
|
||||
XF86XK_DOS: 0x1008FF5A,
|
||||
XF86XK_Documents: 0x1008FF5B,
|
||||
XF86XK_Excel: 0x1008FF5C,
|
||||
XF86XK_Explorer: 0x1008FF5D,
|
||||
XF86XK_Game: 0x1008FF5E,
|
||||
XF86XK_Go: 0x1008FF5F,
|
||||
XF86XK_iTouch: 0x1008FF60,
|
||||
XF86XK_LogOff: 0x1008FF61,
|
||||
XF86XK_Market: 0x1008FF62,
|
||||
XF86XK_Meeting: 0x1008FF63,
|
||||
XF86XK_MenuKB: 0x1008FF65,
|
||||
XF86XK_MenuPB: 0x1008FF66,
|
||||
XF86XK_MySites: 0x1008FF67,
|
||||
XF86XK_New: 0x1008FF68,
|
||||
XF86XK_News: 0x1008FF69,
|
||||
XF86XK_OfficeHome: 0x1008FF6A,
|
||||
XF86XK_Open: 0x1008FF6B,
|
||||
XF86XK_Option: 0x1008FF6C,
|
||||
XF86XK_Paste: 0x1008FF6D,
|
||||
XF86XK_Phone: 0x1008FF6E,
|
||||
XF86XK_Q: 0x1008FF70,
|
||||
XF86XK_Reply: 0x1008FF72,
|
||||
XF86XK_Reload: 0x1008FF73,
|
||||
XF86XK_RotateWindows: 0x1008FF74,
|
||||
XF86XK_RotationPB: 0x1008FF75,
|
||||
XF86XK_RotationKB: 0x1008FF76,
|
||||
XF86XK_Save: 0x1008FF77,
|
||||
XF86XK_ScrollUp: 0x1008FF78,
|
||||
XF86XK_ScrollDown: 0x1008FF79,
|
||||
XF86XK_ScrollClick: 0x1008FF7A,
|
||||
XF86XK_Send: 0x1008FF7B,
|
||||
XF86XK_Spell: 0x1008FF7C,
|
||||
XF86XK_SplitScreen: 0x1008FF7D,
|
||||
XF86XK_Support: 0x1008FF7E,
|
||||
XF86XK_TaskPane: 0x1008FF7F,
|
||||
XF86XK_Terminal: 0x1008FF80,
|
||||
XF86XK_Tools: 0x1008FF81,
|
||||
XF86XK_Travel: 0x1008FF82,
|
||||
XF86XK_UserPB: 0x1008FF84,
|
||||
XF86XK_User1KB: 0x1008FF85,
|
||||
XF86XK_User2KB: 0x1008FF86,
|
||||
XF86XK_Video: 0x1008FF87,
|
||||
XF86XK_WheelButton: 0x1008FF88,
|
||||
XF86XK_Word: 0x1008FF89,
|
||||
XF86XK_Xfer: 0x1008FF8A,
|
||||
XF86XK_ZoomIn: 0x1008FF8B,
|
||||
XF86XK_ZoomOut: 0x1008FF8C,
|
||||
XF86XK_Away: 0x1008FF8D,
|
||||
XF86XK_Messenger: 0x1008FF8E,
|
||||
XF86XK_WebCam: 0x1008FF8F,
|
||||
XF86XK_MailForward: 0x1008FF90,
|
||||
XF86XK_Pictures: 0x1008FF91,
|
||||
XF86XK_Music: 0x1008FF92,
|
||||
XF86XK_Battery: 0x1008FF93,
|
||||
XF86XK_Bluetooth: 0x1008FF94,
|
||||
XF86XK_WLAN: 0x1008FF95,
|
||||
XF86XK_UWB: 0x1008FF96,
|
||||
XF86XK_AudioForward: 0x1008FF97,
|
||||
XF86XK_AudioRepeat: 0x1008FF98,
|
||||
XF86XK_AudioRandomPlay: 0x1008FF99,
|
||||
XF86XK_Subtitle: 0x1008FF9A,
|
||||
XF86XK_AudioCycleTrack: 0x1008FF9B,
|
||||
XF86XK_CycleAngle: 0x1008FF9C,
|
||||
XF86XK_FrameBack: 0x1008FF9D,
|
||||
XF86XK_FrameForward: 0x1008FF9E,
|
||||
XF86XK_Time: 0x1008FF9F,
|
||||
XF86XK_Select: 0x1008FFA0,
|
||||
XF86XK_View: 0x1008FFA1,
|
||||
XF86XK_TopMenu: 0x1008FFA2,
|
||||
XF86XK_Red: 0x1008FFA3,
|
||||
XF86XK_Green: 0x1008FFA4,
|
||||
XF86XK_Yellow: 0x1008FFA5,
|
||||
XF86XK_Blue: 0x1008FFA6,
|
||||
XF86XK_Suspend: 0x1008FFA7,
|
||||
XF86XK_Hibernate: 0x1008FFA8,
|
||||
XF86XK_TouchpadToggle: 0x1008FFA9,
|
||||
XF86XK_TouchpadOn: 0x1008FFB0,
|
||||
XF86XK_TouchpadOff: 0x1008FFB1,
|
||||
XF86XK_AudioMicMute: 0x1008FFB2,
|
||||
XF86XK_Switch_VT_1: 0x1008FE01,
|
||||
XF86XK_Switch_VT_2: 0x1008FE02,
|
||||
XF86XK_Switch_VT_3: 0x1008FE03,
|
||||
XF86XK_Switch_VT_4: 0x1008FE04,
|
||||
XF86XK_Switch_VT_5: 0x1008FE05,
|
||||
XF86XK_Switch_VT_6: 0x1008FE06,
|
||||
XF86XK_Switch_VT_7: 0x1008FE07,
|
||||
XF86XK_Switch_VT_8: 0x1008FE08,
|
||||
XF86XK_Switch_VT_9: 0x1008FE09,
|
||||
XF86XK_Switch_VT_10: 0x1008FE0A,
|
||||
XF86XK_Switch_VT_11: 0x1008FE0B,
|
||||
XF86XK_Switch_VT_12: 0x1008FE0C,
|
||||
XF86XK_Ungrab: 0x1008FE20,
|
||||
XF86XK_ClearGrab: 0x1008FE21,
|
||||
XF86XK_Next_VMode: 0x1008FE22,
|
||||
XF86XK_Prev_VMode: 0x1008FE23,
|
||||
XF86XK_LogWindowTree: 0x1008FE24,
|
||||
XF86XK_LogGrabInfo: 0x1008FE25,
|
||||
};
|
688
public/novnc/core/input/keysymdef.js
Normal file
@ -0,0 +1,688 @@
|
||||
/*
|
||||
* Mapping from Unicode codepoints to X11/RFB keysyms
|
||||
*
|
||||
* This file was automatically generated from keysymdef.h
|
||||
* DO NOT EDIT!
|
||||
*/
|
||||
|
||||
/* Functions at the bottom */
|
||||
|
||||
const codepoints = {
|
||||
0x0100: 0x03c0, // XK_Amacron
|
||||
0x0101: 0x03e0, // XK_amacron
|
||||
0x0102: 0x01c3, // XK_Abreve
|
||||
0x0103: 0x01e3, // XK_abreve
|
||||
0x0104: 0x01a1, // XK_Aogonek
|
||||
0x0105: 0x01b1, // XK_aogonek
|
||||
0x0106: 0x01c6, // XK_Cacute
|
||||
0x0107: 0x01e6, // XK_cacute
|
||||
0x0108: 0x02c6, // XK_Ccircumflex
|
||||
0x0109: 0x02e6, // XK_ccircumflex
|
||||
0x010a: 0x02c5, // XK_Cabovedot
|
||||
0x010b: 0x02e5, // XK_cabovedot
|
||||
0x010c: 0x01c8, // XK_Ccaron
|
||||
0x010d: 0x01e8, // XK_ccaron
|
||||
0x010e: 0x01cf, // XK_Dcaron
|
||||
0x010f: 0x01ef, // XK_dcaron
|
||||
0x0110: 0x01d0, // XK_Dstroke
|
||||
0x0111: 0x01f0, // XK_dstroke
|
||||
0x0112: 0x03aa, // XK_Emacron
|
||||
0x0113: 0x03ba, // XK_emacron
|
||||
0x0116: 0x03cc, // XK_Eabovedot
|
||||
0x0117: 0x03ec, // XK_eabovedot
|
||||
0x0118: 0x01ca, // XK_Eogonek
|
||||
0x0119: 0x01ea, // XK_eogonek
|
||||
0x011a: 0x01cc, // XK_Ecaron
|
||||
0x011b: 0x01ec, // XK_ecaron
|
||||
0x011c: 0x02d8, // XK_Gcircumflex
|
||||
0x011d: 0x02f8, // XK_gcircumflex
|
||||
0x011e: 0x02ab, // XK_Gbreve
|
||||
0x011f: 0x02bb, // XK_gbreve
|
||||
0x0120: 0x02d5, // XK_Gabovedot
|
||||
0x0121: 0x02f5, // XK_gabovedot
|
||||
0x0122: 0x03ab, // XK_Gcedilla
|
||||
0x0123: 0x03bb, // XK_gcedilla
|
||||
0x0124: 0x02a6, // XK_Hcircumflex
|
||||
0x0125: 0x02b6, // XK_hcircumflex
|
||||
0x0126: 0x02a1, // XK_Hstroke
|
||||
0x0127: 0x02b1, // XK_hstroke
|
||||
0x0128: 0x03a5, // XK_Itilde
|
||||
0x0129: 0x03b5, // XK_itilde
|
||||
0x012a: 0x03cf, // XK_Imacron
|
||||
0x012b: 0x03ef, // XK_imacron
|
||||
0x012e: 0x03c7, // XK_Iogonek
|
||||
0x012f: 0x03e7, // XK_iogonek
|
||||
0x0130: 0x02a9, // XK_Iabovedot
|
||||
0x0131: 0x02b9, // XK_idotless
|
||||
0x0134: 0x02ac, // XK_Jcircumflex
|
||||
0x0135: 0x02bc, // XK_jcircumflex
|
||||
0x0136: 0x03d3, // XK_Kcedilla
|
||||
0x0137: 0x03f3, // XK_kcedilla
|
||||
0x0138: 0x03a2, // XK_kra
|
||||
0x0139: 0x01c5, // XK_Lacute
|
||||
0x013a: 0x01e5, // XK_lacute
|
||||
0x013b: 0x03a6, // XK_Lcedilla
|
||||
0x013c: 0x03b6, // XK_lcedilla
|
||||
0x013d: 0x01a5, // XK_Lcaron
|
||||
0x013e: 0x01b5, // XK_lcaron
|
||||
0x0141: 0x01a3, // XK_Lstroke
|
||||
0x0142: 0x01b3, // XK_lstroke
|
||||
0x0143: 0x01d1, // XK_Nacute
|
||||
0x0144: 0x01f1, // XK_nacute
|
||||
0x0145: 0x03d1, // XK_Ncedilla
|
||||
0x0146: 0x03f1, // XK_ncedilla
|
||||
0x0147: 0x01d2, // XK_Ncaron
|
||||
0x0148: 0x01f2, // XK_ncaron
|
||||
0x014a: 0x03bd, // XK_ENG
|
||||
0x014b: 0x03bf, // XK_eng
|
||||
0x014c: 0x03d2, // XK_Omacron
|
||||
0x014d: 0x03f2, // XK_omacron
|
||||
0x0150: 0x01d5, // XK_Odoubleacute
|
||||
0x0151: 0x01f5, // XK_odoubleacute
|
||||
0x0152: 0x13bc, // XK_OE
|
||||
0x0153: 0x13bd, // XK_oe
|
||||
0x0154: 0x01c0, // XK_Racute
|
||||
0x0155: 0x01e0, // XK_racute
|
||||
0x0156: 0x03a3, // XK_Rcedilla
|
||||
0x0157: 0x03b3, // XK_rcedilla
|
||||
0x0158: 0x01d8, // XK_Rcaron
|
||||
0x0159: 0x01f8, // XK_rcaron
|
||||
0x015a: 0x01a6, // XK_Sacute
|
||||
0x015b: 0x01b6, // XK_sacute
|
||||
0x015c: 0x02de, // XK_Scircumflex
|
||||
0x015d: 0x02fe, // XK_scircumflex
|
||||
0x015e: 0x01aa, // XK_Scedilla
|
||||
0x015f: 0x01ba, // XK_scedilla
|
||||
0x0160: 0x01a9, // XK_Scaron
|
||||
0x0161: 0x01b9, // XK_scaron
|
||||
0x0162: 0x01de, // XK_Tcedilla
|
||||
0x0163: 0x01fe, // XK_tcedilla
|
||||
0x0164: 0x01ab, // XK_Tcaron
|
||||
0x0165: 0x01bb, // XK_tcaron
|
||||
0x0166: 0x03ac, // XK_Tslash
|
||||
0x0167: 0x03bc, // XK_tslash
|
||||
0x0168: 0x03dd, // XK_Utilde
|
||||
0x0169: 0x03fd, // XK_utilde
|
||||
0x016a: 0x03de, // XK_Umacron
|
||||
0x016b: 0x03fe, // XK_umacron
|
||||
0x016c: 0x02dd, // XK_Ubreve
|
||||
0x016d: 0x02fd, // XK_ubreve
|
||||
0x016e: 0x01d9, // XK_Uring
|
||||
0x016f: 0x01f9, // XK_uring
|
||||
0x0170: 0x01db, // XK_Udoubleacute
|
||||
0x0171: 0x01fb, // XK_udoubleacute
|
||||
0x0172: 0x03d9, // XK_Uogonek
|
||||
0x0173: 0x03f9, // XK_uogonek
|
||||
0x0178: 0x13be, // XK_Ydiaeresis
|
||||
0x0179: 0x01ac, // XK_Zacute
|
||||
0x017a: 0x01bc, // XK_zacute
|
||||
0x017b: 0x01af, // XK_Zabovedot
|
||||
0x017c: 0x01bf, // XK_zabovedot
|
||||
0x017d: 0x01ae, // XK_Zcaron
|
||||
0x017e: 0x01be, // XK_zcaron
|
||||
0x0192: 0x08f6, // XK_function
|
||||
0x01d2: 0x10001d1, // XK_Ocaron
|
||||
0x02c7: 0x01b7, // XK_caron
|
||||
0x02d8: 0x01a2, // XK_breve
|
||||
0x02d9: 0x01ff, // XK_abovedot
|
||||
0x02db: 0x01b2, // XK_ogonek
|
||||
0x02dd: 0x01bd, // XK_doubleacute
|
||||
0x0385: 0x07ae, // XK_Greek_accentdieresis
|
||||
0x0386: 0x07a1, // XK_Greek_ALPHAaccent
|
||||
0x0388: 0x07a2, // XK_Greek_EPSILONaccent
|
||||
0x0389: 0x07a3, // XK_Greek_ETAaccent
|
||||
0x038a: 0x07a4, // XK_Greek_IOTAaccent
|
||||
0x038c: 0x07a7, // XK_Greek_OMICRONaccent
|
||||
0x038e: 0x07a8, // XK_Greek_UPSILONaccent
|
||||
0x038f: 0x07ab, // XK_Greek_OMEGAaccent
|
||||
0x0390: 0x07b6, // XK_Greek_iotaaccentdieresis
|
||||
0x0391: 0x07c1, // XK_Greek_ALPHA
|
||||
0x0392: 0x07c2, // XK_Greek_BETA
|
||||
0x0393: 0x07c3, // XK_Greek_GAMMA
|
||||
0x0394: 0x07c4, // XK_Greek_DELTA
|
||||
0x0395: 0x07c5, // XK_Greek_EPSILON
|
||||
0x0396: 0x07c6, // XK_Greek_ZETA
|
||||
0x0397: 0x07c7, // XK_Greek_ETA
|
||||
0x0398: 0x07c8, // XK_Greek_THETA
|
||||
0x0399: 0x07c9, // XK_Greek_IOTA
|
||||
0x039a: 0x07ca, // XK_Greek_KAPPA
|
||||
0x039b: 0x07cb, // XK_Greek_LAMDA
|
||||
0x039c: 0x07cc, // XK_Greek_MU
|
||||
0x039d: 0x07cd, // XK_Greek_NU
|
||||
0x039e: 0x07ce, // XK_Greek_XI
|
||||
0x039f: 0x07cf, // XK_Greek_OMICRON
|
||||
0x03a0: 0x07d0, // XK_Greek_PI
|
||||
0x03a1: 0x07d1, // XK_Greek_RHO
|
||||
0x03a3: 0x07d2, // XK_Greek_SIGMA
|
||||
0x03a4: 0x07d4, // XK_Greek_TAU
|
||||
0x03a5: 0x07d5, // XK_Greek_UPSILON
|
||||
0x03a6: 0x07d6, // XK_Greek_PHI
|
||||
0x03a7: 0x07d7, // XK_Greek_CHI
|
||||
0x03a8: 0x07d8, // XK_Greek_PSI
|
||||
0x03a9: 0x07d9, // XK_Greek_OMEGA
|
||||
0x03aa: 0x07a5, // XK_Greek_IOTAdieresis
|
||||
0x03ab: 0x07a9, // XK_Greek_UPSILONdieresis
|
||||
0x03ac: 0x07b1, // XK_Greek_alphaaccent
|
||||
0x03ad: 0x07b2, // XK_Greek_epsilonaccent
|
||||
0x03ae: 0x07b3, // XK_Greek_etaaccent
|
||||
0x03af: 0x07b4, // XK_Greek_iotaaccent
|
||||
0x03b0: 0x07ba, // XK_Greek_upsilonaccentdieresis
|
||||
0x03b1: 0x07e1, // XK_Greek_alpha
|
||||
0x03b2: 0x07e2, // XK_Greek_beta
|
||||
0x03b3: 0x07e3, // XK_Greek_gamma
|
||||
0x03b4: 0x07e4, // XK_Greek_delta
|
||||
0x03b5: 0x07e5, // XK_Greek_epsilon
|
||||
0x03b6: 0x07e6, // XK_Greek_zeta
|
||||
0x03b7: 0x07e7, // XK_Greek_eta
|
||||
0x03b8: 0x07e8, // XK_Greek_theta
|
||||
0x03b9: 0x07e9, // XK_Greek_iota
|
||||
0x03ba: 0x07ea, // XK_Greek_kappa
|
||||
0x03bb: 0x07eb, // XK_Greek_lamda
|
||||
0x03bc: 0x07ec, // XK_Greek_mu
|
||||
0x03bd: 0x07ed, // XK_Greek_nu
|
||||
0x03be: 0x07ee, // XK_Greek_xi
|
||||
0x03bf: 0x07ef, // XK_Greek_omicron
|
||||
0x03c0: 0x07f0, // XK_Greek_pi
|
||||
0x03c1: 0x07f1, // XK_Greek_rho
|
||||
0x03c2: 0x07f3, // XK_Greek_finalsmallsigma
|
||||
0x03c3: 0x07f2, // XK_Greek_sigma
|
||||
0x03c4: 0x07f4, // XK_Greek_tau
|
||||
0x03c5: 0x07f5, // XK_Greek_upsilon
|
||||
0x03c6: 0x07f6, // XK_Greek_phi
|
||||
0x03c7: 0x07f7, // XK_Greek_chi
|
||||
0x03c8: 0x07f8, // XK_Greek_psi
|
||||
0x03c9: 0x07f9, // XK_Greek_omega
|
||||
0x03ca: 0x07b5, // XK_Greek_iotadieresis
|
||||
0x03cb: 0x07b9, // XK_Greek_upsilondieresis
|
||||
0x03cc: 0x07b7, // XK_Greek_omicronaccent
|
||||
0x03cd: 0x07b8, // XK_Greek_upsilonaccent
|
||||
0x03ce: 0x07bb, // XK_Greek_omegaaccent
|
||||
0x0401: 0x06b3, // XK_Cyrillic_IO
|
||||
0x0402: 0x06b1, // XK_Serbian_DJE
|
||||
0x0403: 0x06b2, // XK_Macedonia_GJE
|
||||
0x0404: 0x06b4, // XK_Ukrainian_IE
|
||||
0x0405: 0x06b5, // XK_Macedonia_DSE
|
||||
0x0406: 0x06b6, // XK_Ukrainian_I
|
||||
0x0407: 0x06b7, // XK_Ukrainian_YI
|
||||
0x0408: 0x06b8, // XK_Cyrillic_JE
|
||||
0x0409: 0x06b9, // XK_Cyrillic_LJE
|
||||
0x040a: 0x06ba, // XK_Cyrillic_NJE
|
||||
0x040b: 0x06bb, // XK_Serbian_TSHE
|
||||
0x040c: 0x06bc, // XK_Macedonia_KJE
|
||||
0x040e: 0x06be, // XK_Byelorussian_SHORTU
|
||||
0x040f: 0x06bf, // XK_Cyrillic_DZHE
|
||||
0x0410: 0x06e1, // XK_Cyrillic_A
|
||||
0x0411: 0x06e2, // XK_Cyrillic_BE
|
||||
0x0412: 0x06f7, // XK_Cyrillic_VE
|
||||
0x0413: 0x06e7, // XK_Cyrillic_GHE
|
||||
0x0414: 0x06e4, // XK_Cyrillic_DE
|
||||
0x0415: 0x06e5, // XK_Cyrillic_IE
|
||||
0x0416: 0x06f6, // XK_Cyrillic_ZHE
|
||||
0x0417: 0x06fa, // XK_Cyrillic_ZE
|
||||
0x0418: 0x06e9, // XK_Cyrillic_I
|
||||
0x0419: 0x06ea, // XK_Cyrillic_SHORTI
|
||||
0x041a: 0x06eb, // XK_Cyrillic_KA
|
||||
0x041b: 0x06ec, // XK_Cyrillic_EL
|
||||
0x041c: 0x06ed, // XK_Cyrillic_EM
|
||||
0x041d: 0x06ee, // XK_Cyrillic_EN
|
||||
0x041e: 0x06ef, // XK_Cyrillic_O
|
||||
0x041f: 0x06f0, // XK_Cyrillic_PE
|
||||
0x0420: 0x06f2, // XK_Cyrillic_ER
|
||||
0x0421: 0x06f3, // XK_Cyrillic_ES
|
||||
0x0422: 0x06f4, // XK_Cyrillic_TE
|
||||
0x0423: 0x06f5, // XK_Cyrillic_U
|
||||
0x0424: 0x06e6, // XK_Cyrillic_EF
|
||||
0x0425: 0x06e8, // XK_Cyrillic_HA
|
||||
0x0426: 0x06e3, // XK_Cyrillic_TSE
|
||||
0x0427: 0x06fe, // XK_Cyrillic_CHE
|
||||
0x0428: 0x06fb, // XK_Cyrillic_SHA
|
||||
0x0429: 0x06fd, // XK_Cyrillic_SHCHA
|
||||
0x042a: 0x06ff, // XK_Cyrillic_HARDSIGN
|
||||
0x042b: 0x06f9, // XK_Cyrillic_YERU
|
||||
0x042c: 0x06f8, // XK_Cyrillic_SOFTSIGN
|
||||
0x042d: 0x06fc, // XK_Cyrillic_E
|
||||
0x042e: 0x06e0, // XK_Cyrillic_YU
|
||||
0x042f: 0x06f1, // XK_Cyrillic_YA
|
||||
0x0430: 0x06c1, // XK_Cyrillic_a
|
||||
0x0431: 0x06c2, // XK_Cyrillic_be
|
||||
0x0432: 0x06d7, // XK_Cyrillic_ve
|
||||
0x0433: 0x06c7, // XK_Cyrillic_ghe
|
||||
0x0434: 0x06c4, // XK_Cyrillic_de
|
||||
0x0435: 0x06c5, // XK_Cyrillic_ie
|
||||
0x0436: 0x06d6, // XK_Cyrillic_zhe
|
||||
0x0437: 0x06da, // XK_Cyrillic_ze
|
||||
0x0438: 0x06c9, // XK_Cyrillic_i
|
||||
0x0439: 0x06ca, // XK_Cyrillic_shorti
|
||||
0x043a: 0x06cb, // XK_Cyrillic_ka
|
||||
0x043b: 0x06cc, // XK_Cyrillic_el
|
||||
0x043c: 0x06cd, // XK_Cyrillic_em
|
||||
0x043d: 0x06ce, // XK_Cyrillic_en
|
||||
0x043e: 0x06cf, // XK_Cyrillic_o
|
||||
0x043f: 0x06d0, // XK_Cyrillic_pe
|
||||
0x0440: 0x06d2, // XK_Cyrillic_er
|
||||
0x0441: 0x06d3, // XK_Cyrillic_es
|
||||
0x0442: 0x06d4, // XK_Cyrillic_te
|
||||
0x0443: 0x06d5, // XK_Cyrillic_u
|
||||
0x0444: 0x06c6, // XK_Cyrillic_ef
|
||||
0x0445: 0x06c8, // XK_Cyrillic_ha
|
||||
0x0446: 0x06c3, // XK_Cyrillic_tse
|
||||
0x0447: 0x06de, // XK_Cyrillic_che
|
||||
0x0448: 0x06db, // XK_Cyrillic_sha
|
||||
0x0449: 0x06dd, // XK_Cyrillic_shcha
|
||||
0x044a: 0x06df, // XK_Cyrillic_hardsign
|
||||
0x044b: 0x06d9, // XK_Cyrillic_yeru
|
||||
0x044c: 0x06d8, // XK_Cyrillic_softsign
|
||||
0x044d: 0x06dc, // XK_Cyrillic_e
|
||||
0x044e: 0x06c0, // XK_Cyrillic_yu
|
||||
0x044f: 0x06d1, // XK_Cyrillic_ya
|
||||
0x0451: 0x06a3, // XK_Cyrillic_io
|
||||
0x0452: 0x06a1, // XK_Serbian_dje
|
||||
0x0453: 0x06a2, // XK_Macedonia_gje
|
||||
0x0454: 0x06a4, // XK_Ukrainian_ie
|
||||
0x0455: 0x06a5, // XK_Macedonia_dse
|
||||
0x0456: 0x06a6, // XK_Ukrainian_i
|
||||
0x0457: 0x06a7, // XK_Ukrainian_yi
|
||||
0x0458: 0x06a8, // XK_Cyrillic_je
|
||||
0x0459: 0x06a9, // XK_Cyrillic_lje
|
||||
0x045a: 0x06aa, // XK_Cyrillic_nje
|
||||
0x045b: 0x06ab, // XK_Serbian_tshe
|
||||
0x045c: 0x06ac, // XK_Macedonia_kje
|
||||
0x045e: 0x06ae, // XK_Byelorussian_shortu
|
||||
0x045f: 0x06af, // XK_Cyrillic_dzhe
|
||||
0x0490: 0x06bd, // XK_Ukrainian_GHE_WITH_UPTURN
|
||||
0x0491: 0x06ad, // XK_Ukrainian_ghe_with_upturn
|
||||
0x05d0: 0x0ce0, // XK_hebrew_aleph
|
||||
0x05d1: 0x0ce1, // XK_hebrew_bet
|
||||
0x05d2: 0x0ce2, // XK_hebrew_gimel
|
||||
0x05d3: 0x0ce3, // XK_hebrew_dalet
|
||||
0x05d4: 0x0ce4, // XK_hebrew_he
|
||||
0x05d5: 0x0ce5, // XK_hebrew_waw
|
||||
0x05d6: 0x0ce6, // XK_hebrew_zain
|
||||
0x05d7: 0x0ce7, // XK_hebrew_chet
|
||||
0x05d8: 0x0ce8, // XK_hebrew_tet
|
||||
0x05d9: 0x0ce9, // XK_hebrew_yod
|
||||
0x05da: 0x0cea, // XK_hebrew_finalkaph
|
||||
0x05db: 0x0ceb, // XK_hebrew_kaph
|
||||
0x05dc: 0x0cec, // XK_hebrew_lamed
|
||||
0x05dd: 0x0ced, // XK_hebrew_finalmem
|
||||
0x05de: 0x0cee, // XK_hebrew_mem
|
||||
0x05df: 0x0cef, // XK_hebrew_finalnun
|
||||
0x05e0: 0x0cf0, // XK_hebrew_nun
|
||||
0x05e1: 0x0cf1, // XK_hebrew_samech
|
||||
0x05e2: 0x0cf2, // XK_hebrew_ayin
|
||||
0x05e3: 0x0cf3, // XK_hebrew_finalpe
|
||||
0x05e4: 0x0cf4, // XK_hebrew_pe
|
||||
0x05e5: 0x0cf5, // XK_hebrew_finalzade
|
||||
0x05e6: 0x0cf6, // XK_hebrew_zade
|
||||
0x05e7: 0x0cf7, // XK_hebrew_qoph
|
||||
0x05e8: 0x0cf8, // XK_hebrew_resh
|
||||
0x05e9: 0x0cf9, // XK_hebrew_shin
|
||||
0x05ea: 0x0cfa, // XK_hebrew_taw
|
||||
0x060c: 0x05ac, // XK_Arabic_comma
|
||||
0x061b: 0x05bb, // XK_Arabic_semicolon
|
||||
0x061f: 0x05bf, // XK_Arabic_question_mark
|
||||
0x0621: 0x05c1, // XK_Arabic_hamza
|
||||
0x0622: 0x05c2, // XK_Arabic_maddaonalef
|
||||
0x0623: 0x05c3, // XK_Arabic_hamzaonalef
|
||||
0x0624: 0x05c4, // XK_Arabic_hamzaonwaw
|
||||
0x0625: 0x05c5, // XK_Arabic_hamzaunderalef
|
||||
0x0626: 0x05c6, // XK_Arabic_hamzaonyeh
|
||||
0x0627: 0x05c7, // XK_Arabic_alef
|
||||
0x0628: 0x05c8, // XK_Arabic_beh
|
||||
0x0629: 0x05c9, // XK_Arabic_tehmarbuta
|
||||
0x062a: 0x05ca, // XK_Arabic_teh
|
||||
0x062b: 0x05cb, // XK_Arabic_theh
|
||||
0x062c: 0x05cc, // XK_Arabic_jeem
|
||||
0x062d: 0x05cd, // XK_Arabic_hah
|
||||
0x062e: 0x05ce, // XK_Arabic_khah
|
||||
0x062f: 0x05cf, // XK_Arabic_dal
|
||||
0x0630: 0x05d0, // XK_Arabic_thal
|
||||
0x0631: 0x05d1, // XK_Arabic_ra
|
||||
0x0632: 0x05d2, // XK_Arabic_zain
|
||||
0x0633: 0x05d3, // XK_Arabic_seen
|
||||
0x0634: 0x05d4, // XK_Arabic_sheen
|
||||
0x0635: 0x05d5, // XK_Arabic_sad
|
||||
0x0636: 0x05d6, // XK_Arabic_dad
|
||||
0x0637: 0x05d7, // XK_Arabic_tah
|
||||
0x0638: 0x05d8, // XK_Arabic_zah
|
||||
0x0639: 0x05d9, // XK_Arabic_ain
|
||||
0x063a: 0x05da, // XK_Arabic_ghain
|
||||
0x0640: 0x05e0, // XK_Arabic_tatweel
|
||||
0x0641: 0x05e1, // XK_Arabic_feh
|
||||
0x0642: 0x05e2, // XK_Arabic_qaf
|
||||
0x0643: 0x05e3, // XK_Arabic_kaf
|
||||
0x0644: 0x05e4, // XK_Arabic_lam
|
||||
0x0645: 0x05e5, // XK_Arabic_meem
|
||||
0x0646: 0x05e6, // XK_Arabic_noon
|
||||
0x0647: 0x05e7, // XK_Arabic_ha
|
||||
0x0648: 0x05e8, // XK_Arabic_waw
|
||||
0x0649: 0x05e9, // XK_Arabic_alefmaksura
|
||||
0x064a: 0x05ea, // XK_Arabic_yeh
|
||||
0x064b: 0x05eb, // XK_Arabic_fathatan
|
||||
0x064c: 0x05ec, // XK_Arabic_dammatan
|
||||
0x064d: 0x05ed, // XK_Arabic_kasratan
|
||||
0x064e: 0x05ee, // XK_Arabic_fatha
|
||||
0x064f: 0x05ef, // XK_Arabic_damma
|
||||
0x0650: 0x05f0, // XK_Arabic_kasra
|
||||
0x0651: 0x05f1, // XK_Arabic_shadda
|
||||
0x0652: 0x05f2, // XK_Arabic_sukun
|
||||
0x0e01: 0x0da1, // XK_Thai_kokai
|
||||
0x0e02: 0x0da2, // XK_Thai_khokhai
|
||||
0x0e03: 0x0da3, // XK_Thai_khokhuat
|
||||
0x0e04: 0x0da4, // XK_Thai_khokhwai
|
||||
0x0e05: 0x0da5, // XK_Thai_khokhon
|
||||
0x0e06: 0x0da6, // XK_Thai_khorakhang
|
||||
0x0e07: 0x0da7, // XK_Thai_ngongu
|
||||
0x0e08: 0x0da8, // XK_Thai_chochan
|
||||
0x0e09: 0x0da9, // XK_Thai_choching
|
||||
0x0e0a: 0x0daa, // XK_Thai_chochang
|
||||
0x0e0b: 0x0dab, // XK_Thai_soso
|
||||
0x0e0c: 0x0dac, // XK_Thai_chochoe
|
||||
0x0e0d: 0x0dad, // XK_Thai_yoying
|
||||
0x0e0e: 0x0dae, // XK_Thai_dochada
|
||||
0x0e0f: 0x0daf, // XK_Thai_topatak
|
||||
0x0e10: 0x0db0, // XK_Thai_thothan
|
||||
0x0e11: 0x0db1, // XK_Thai_thonangmontho
|
||||
0x0e12: 0x0db2, // XK_Thai_thophuthao
|
||||
0x0e13: 0x0db3, // XK_Thai_nonen
|
||||
0x0e14: 0x0db4, // XK_Thai_dodek
|
||||
0x0e15: 0x0db5, // XK_Thai_totao
|
||||
0x0e16: 0x0db6, // XK_Thai_thothung
|
||||
0x0e17: 0x0db7, // XK_Thai_thothahan
|
||||
0x0e18: 0x0db8, // XK_Thai_thothong
|
||||
0x0e19: 0x0db9, // XK_Thai_nonu
|
||||
0x0e1a: 0x0dba, // XK_Thai_bobaimai
|
||||
0x0e1b: 0x0dbb, // XK_Thai_popla
|
||||
0x0e1c: 0x0dbc, // XK_Thai_phophung
|
||||
0x0e1d: 0x0dbd, // XK_Thai_fofa
|
||||
0x0e1e: 0x0dbe, // XK_Thai_phophan
|
||||
0x0e1f: 0x0dbf, // XK_Thai_fofan
|
||||
0x0e20: 0x0dc0, // XK_Thai_phosamphao
|
||||
0x0e21: 0x0dc1, // XK_Thai_moma
|
||||
0x0e22: 0x0dc2, // XK_Thai_yoyak
|
||||
0x0e23: 0x0dc3, // XK_Thai_rorua
|
||||
0x0e24: 0x0dc4, // XK_Thai_ru
|
||||
0x0e25: 0x0dc5, // XK_Thai_loling
|
||||
0x0e26: 0x0dc6, // XK_Thai_lu
|
||||
0x0e27: 0x0dc7, // XK_Thai_wowaen
|
||||
0x0e28: 0x0dc8, // XK_Thai_sosala
|
||||
0x0e29: 0x0dc9, // XK_Thai_sorusi
|
||||
0x0e2a: 0x0dca, // XK_Thai_sosua
|
||||
0x0e2b: 0x0dcb, // XK_Thai_hohip
|
||||
0x0e2c: 0x0dcc, // XK_Thai_lochula
|
||||
0x0e2d: 0x0dcd, // XK_Thai_oang
|
||||
0x0e2e: 0x0dce, // XK_Thai_honokhuk
|
||||
0x0e2f: 0x0dcf, // XK_Thai_paiyannoi
|
||||
0x0e30: 0x0dd0, // XK_Thai_saraa
|
||||
0x0e31: 0x0dd1, // XK_Thai_maihanakat
|
||||
0x0e32: 0x0dd2, // XK_Thai_saraaa
|
||||
0x0e33: 0x0dd3, // XK_Thai_saraam
|
||||
0x0e34: 0x0dd4, // XK_Thai_sarai
|
||||
0x0e35: 0x0dd5, // XK_Thai_saraii
|
||||
0x0e36: 0x0dd6, // XK_Thai_saraue
|
||||
0x0e37: 0x0dd7, // XK_Thai_sarauee
|
||||
0x0e38: 0x0dd8, // XK_Thai_sarau
|
||||
0x0e39: 0x0dd9, // XK_Thai_sarauu
|
||||
0x0e3a: 0x0dda, // XK_Thai_phinthu
|
||||
0x0e3f: 0x0ddf, // XK_Thai_baht
|
||||
0x0e40: 0x0de0, // XK_Thai_sarae
|
||||
0x0e41: 0x0de1, // XK_Thai_saraae
|
||||
0x0e42: 0x0de2, // XK_Thai_sarao
|
||||
0x0e43: 0x0de3, // XK_Thai_saraaimaimuan
|
||||
0x0e44: 0x0de4, // XK_Thai_saraaimaimalai
|
||||
0x0e45: 0x0de5, // XK_Thai_lakkhangyao
|
||||
0x0e46: 0x0de6, // XK_Thai_maiyamok
|
||||
0x0e47: 0x0de7, // XK_Thai_maitaikhu
|
||||
0x0e48: 0x0de8, // XK_Thai_maiek
|
||||
0x0e49: 0x0de9, // XK_Thai_maitho
|
||||
0x0e4a: 0x0dea, // XK_Thai_maitri
|
||||
0x0e4b: 0x0deb, // XK_Thai_maichattawa
|
||||
0x0e4c: 0x0dec, // XK_Thai_thanthakhat
|
||||
0x0e4d: 0x0ded, // XK_Thai_nikhahit
|
||||
0x0e50: 0x0df0, // XK_Thai_leksun
|
||||
0x0e51: 0x0df1, // XK_Thai_leknung
|
||||
0x0e52: 0x0df2, // XK_Thai_leksong
|
||||
0x0e53: 0x0df3, // XK_Thai_leksam
|
||||
0x0e54: 0x0df4, // XK_Thai_leksi
|
||||
0x0e55: 0x0df5, // XK_Thai_lekha
|
||||
0x0e56: 0x0df6, // XK_Thai_lekhok
|
||||
0x0e57: 0x0df7, // XK_Thai_lekchet
|
||||
0x0e58: 0x0df8, // XK_Thai_lekpaet
|
||||
0x0e59: 0x0df9, // XK_Thai_lekkao
|
||||
0x2002: 0x0aa2, // XK_enspace
|
||||
0x2003: 0x0aa1, // XK_emspace
|
||||
0x2004: 0x0aa3, // XK_em3space
|
||||
0x2005: 0x0aa4, // XK_em4space
|
||||
0x2007: 0x0aa5, // XK_digitspace
|
||||
0x2008: 0x0aa6, // XK_punctspace
|
||||
0x2009: 0x0aa7, // XK_thinspace
|
||||
0x200a: 0x0aa8, // XK_hairspace
|
||||
0x2012: 0x0abb, // XK_figdash
|
||||
0x2013: 0x0aaa, // XK_endash
|
||||
0x2014: 0x0aa9, // XK_emdash
|
||||
0x2015: 0x07af, // XK_Greek_horizbar
|
||||
0x2017: 0x0cdf, // XK_hebrew_doublelowline
|
||||
0x2018: 0x0ad0, // XK_leftsinglequotemark
|
||||
0x2019: 0x0ad1, // XK_rightsinglequotemark
|
||||
0x201a: 0x0afd, // XK_singlelowquotemark
|
||||
0x201c: 0x0ad2, // XK_leftdoublequotemark
|
||||
0x201d: 0x0ad3, // XK_rightdoublequotemark
|
||||
0x201e: 0x0afe, // XK_doublelowquotemark
|
||||
0x2020: 0x0af1, // XK_dagger
|
||||
0x2021: 0x0af2, // XK_doubledagger
|
||||
0x2022: 0x0ae6, // XK_enfilledcircbullet
|
||||
0x2025: 0x0aaf, // XK_doubbaselinedot
|
||||
0x2026: 0x0aae, // XK_ellipsis
|
||||
0x2030: 0x0ad5, // XK_permille
|
||||
0x2032: 0x0ad6, // XK_minutes
|
||||
0x2033: 0x0ad7, // XK_seconds
|
||||
0x2038: 0x0afc, // XK_caret
|
||||
0x203e: 0x047e, // XK_overline
|
||||
0x20a9: 0x0eff, // XK_Korean_Won
|
||||
0x20ac: 0x20ac, // XK_EuroSign
|
||||
0x2105: 0x0ab8, // XK_careof
|
||||
0x2116: 0x06b0, // XK_numerosign
|
||||
0x2117: 0x0afb, // XK_phonographcopyright
|
||||
0x211e: 0x0ad4, // XK_prescription
|
||||
0x2122: 0x0ac9, // XK_trademark
|
||||
0x2153: 0x0ab0, // XK_onethird
|
||||
0x2154: 0x0ab1, // XK_twothirds
|
||||
0x2155: 0x0ab2, // XK_onefifth
|
||||
0x2156: 0x0ab3, // XK_twofifths
|
||||
0x2157: 0x0ab4, // XK_threefifths
|
||||
0x2158: 0x0ab5, // XK_fourfifths
|
||||
0x2159: 0x0ab6, // XK_onesixth
|
||||
0x215a: 0x0ab7, // XK_fivesixths
|
||||
0x215b: 0x0ac3, // XK_oneeighth
|
||||
0x215c: 0x0ac4, // XK_threeeighths
|
||||
0x215d: 0x0ac5, // XK_fiveeighths
|
||||
0x215e: 0x0ac6, // XK_seveneighths
|
||||
0x2190: 0x08fb, // XK_leftarrow
|
||||
0x2191: 0x08fc, // XK_uparrow
|
||||
0x2192: 0x08fd, // XK_rightarrow
|
||||
0x2193: 0x08fe, // XK_downarrow
|
||||
0x21d2: 0x08ce, // XK_implies
|
||||
0x21d4: 0x08cd, // XK_ifonlyif
|
||||
0x2202: 0x08ef, // XK_partialderivative
|
||||
0x2207: 0x08c5, // XK_nabla
|
||||
0x2218: 0x0bca, // XK_jot
|
||||
0x221a: 0x08d6, // XK_radical
|
||||
0x221d: 0x08c1, // XK_variation
|
||||
0x221e: 0x08c2, // XK_infinity
|
||||
0x2227: 0x08de, // XK_logicaland
|
||||
0x2228: 0x08df, // XK_logicalor
|
||||
0x2229: 0x08dc, // XK_intersection
|
||||
0x222a: 0x08dd, // XK_union
|
||||
0x222b: 0x08bf, // XK_integral
|
||||
0x2234: 0x08c0, // XK_therefore
|
||||
0x223c: 0x08c8, // XK_approximate
|
||||
0x2243: 0x08c9, // XK_similarequal
|
||||
0x2245: 0x1002248, // XK_approxeq
|
||||
0x2260: 0x08bd, // XK_notequal
|
||||
0x2261: 0x08cf, // XK_identical
|
||||
0x2264: 0x08bc, // XK_lessthanequal
|
||||
0x2265: 0x08be, // XK_greaterthanequal
|
||||
0x2282: 0x08da, // XK_includedin
|
||||
0x2283: 0x08db, // XK_includes
|
||||
0x22a2: 0x0bfc, // XK_righttack
|
||||
0x22a3: 0x0bdc, // XK_lefttack
|
||||
0x22a4: 0x0bc2, // XK_downtack
|
||||
0x22a5: 0x0bce, // XK_uptack
|
||||
0x2308: 0x0bd3, // XK_upstile
|
||||
0x230a: 0x0bc4, // XK_downstile
|
||||
0x2315: 0x0afa, // XK_telephonerecorder
|
||||
0x2320: 0x08a4, // XK_topintegral
|
||||
0x2321: 0x08a5, // XK_botintegral
|
||||
0x2395: 0x0bcc, // XK_quad
|
||||
0x239b: 0x08ab, // XK_topleftparens
|
||||
0x239d: 0x08ac, // XK_botleftparens
|
||||
0x239e: 0x08ad, // XK_toprightparens
|
||||
0x23a0: 0x08ae, // XK_botrightparens
|
||||
0x23a1: 0x08a7, // XK_topleftsqbracket
|
||||
0x23a3: 0x08a8, // XK_botleftsqbracket
|
||||
0x23a4: 0x08a9, // XK_toprightsqbracket
|
||||
0x23a6: 0x08aa, // XK_botrightsqbracket
|
||||
0x23a8: 0x08af, // XK_leftmiddlecurlybrace
|
||||
0x23ac: 0x08b0, // XK_rightmiddlecurlybrace
|
||||
0x23b7: 0x08a1, // XK_leftradical
|
||||
0x23ba: 0x09ef, // XK_horizlinescan1
|
||||
0x23bb: 0x09f0, // XK_horizlinescan3
|
||||
0x23bc: 0x09f2, // XK_horizlinescan7
|
||||
0x23bd: 0x09f3, // XK_horizlinescan9
|
||||
0x2409: 0x09e2, // XK_ht
|
||||
0x240a: 0x09e5, // XK_lf
|
||||
0x240b: 0x09e9, // XK_vt
|
||||
0x240c: 0x09e3, // XK_ff
|
||||
0x240d: 0x09e4, // XK_cr
|
||||
0x2423: 0x0aac, // XK_signifblank
|
||||
0x2424: 0x09e8, // XK_nl
|
||||
0x2500: 0x08a3, // XK_horizconnector
|
||||
0x2502: 0x08a6, // XK_vertconnector
|
||||
0x250c: 0x08a2, // XK_topleftradical
|
||||
0x2510: 0x09eb, // XK_uprightcorner
|
||||
0x2514: 0x09ed, // XK_lowleftcorner
|
||||
0x2518: 0x09ea, // XK_lowrightcorner
|
||||
0x251c: 0x09f4, // XK_leftt
|
||||
0x2524: 0x09f5, // XK_rightt
|
||||
0x252c: 0x09f7, // XK_topt
|
||||
0x2534: 0x09f6, // XK_bott
|
||||
0x253c: 0x09ee, // XK_crossinglines
|
||||
0x2592: 0x09e1, // XK_checkerboard
|
||||
0x25aa: 0x0ae7, // XK_enfilledsqbullet
|
||||
0x25ab: 0x0ae1, // XK_enopensquarebullet
|
||||
0x25ac: 0x0adb, // XK_filledrectbullet
|
||||
0x25ad: 0x0ae2, // XK_openrectbullet
|
||||
0x25ae: 0x0adf, // XK_emfilledrect
|
||||
0x25af: 0x0acf, // XK_emopenrectangle
|
||||
0x25b2: 0x0ae8, // XK_filledtribulletup
|
||||
0x25b3: 0x0ae3, // XK_opentribulletup
|
||||
0x25b6: 0x0add, // XK_filledrighttribullet
|
||||
0x25b7: 0x0acd, // XK_rightopentriangle
|
||||
0x25bc: 0x0ae9, // XK_filledtribulletdown
|
||||
0x25bd: 0x0ae4, // XK_opentribulletdown
|
||||
0x25c0: 0x0adc, // XK_filledlefttribullet
|
||||
0x25c1: 0x0acc, // XK_leftopentriangle
|
||||
0x25c6: 0x09e0, // XK_soliddiamond
|
||||
0x25cb: 0x0ace, // XK_emopencircle
|
||||
0x25cf: 0x0ade, // XK_emfilledcircle
|
||||
0x25e6: 0x0ae0, // XK_enopencircbullet
|
||||
0x2606: 0x0ae5, // XK_openstar
|
||||
0x260e: 0x0af9, // XK_telephone
|
||||
0x2613: 0x0aca, // XK_signaturemark
|
||||
0x261c: 0x0aea, // XK_leftpointer
|
||||
0x261e: 0x0aeb, // XK_rightpointer
|
||||
0x2640: 0x0af8, // XK_femalesymbol
|
||||
0x2642: 0x0af7, // XK_malesymbol
|
||||
0x2663: 0x0aec, // XK_club
|
||||
0x2665: 0x0aee, // XK_heart
|
||||
0x2666: 0x0aed, // XK_diamond
|
||||
0x266d: 0x0af6, // XK_musicalflat
|
||||
0x266f: 0x0af5, // XK_musicalsharp
|
||||
0x2713: 0x0af3, // XK_checkmark
|
||||
0x2717: 0x0af4, // XK_ballotcross
|
||||
0x271d: 0x0ad9, // XK_latincross
|
||||
0x2720: 0x0af0, // XK_maltesecross
|
||||
0x27e8: 0x0abc, // XK_leftanglebracket
|
||||
0x27e9: 0x0abe, // XK_rightanglebracket
|
||||
0x3001: 0x04a4, // XK_kana_comma
|
||||
0x3002: 0x04a1, // XK_kana_fullstop
|
||||
0x300c: 0x04a2, // XK_kana_openingbracket
|
||||
0x300d: 0x04a3, // XK_kana_closingbracket
|
||||
0x309b: 0x04de, // XK_voicedsound
|
||||
0x309c: 0x04df, // XK_semivoicedsound
|
||||
0x30a1: 0x04a7, // XK_kana_a
|
||||
0x30a2: 0x04b1, // XK_kana_A
|
||||
0x30a3: 0x04a8, // XK_kana_i
|
||||
0x30a4: 0x04b2, // XK_kana_I
|
||||
0x30a5: 0x04a9, // XK_kana_u
|
||||
0x30a6: 0x04b3, // XK_kana_U
|
||||
0x30a7: 0x04aa, // XK_kana_e
|
||||
0x30a8: 0x04b4, // XK_kana_E
|
||||
0x30a9: 0x04ab, // XK_kana_o
|
||||
0x30aa: 0x04b5, // XK_kana_O
|
||||
0x30ab: 0x04b6, // XK_kana_KA
|
||||
0x30ad: 0x04b7, // XK_kana_KI
|
||||
0x30af: 0x04b8, // XK_kana_KU
|
||||
0x30b1: 0x04b9, // XK_kana_KE
|
||||
0x30b3: 0x04ba, // XK_kana_KO
|
||||
0x30b5: 0x04bb, // XK_kana_SA
|
||||
0x30b7: 0x04bc, // XK_kana_SHI
|
||||
0x30b9: 0x04bd, // XK_kana_SU
|
||||
0x30bb: 0x04be, // XK_kana_SE
|
||||
0x30bd: 0x04bf, // XK_kana_SO
|
||||
0x30bf: 0x04c0, // XK_kana_TA
|
||||
0x30c1: 0x04c1, // XK_kana_CHI
|
||||
0x30c3: 0x04af, // XK_kana_tsu
|
||||
0x30c4: 0x04c2, // XK_kana_TSU
|
||||
0x30c6: 0x04c3, // XK_kana_TE
|
||||
0x30c8: 0x04c4, // XK_kana_TO
|
||||
0x30ca: 0x04c5, // XK_kana_NA
|
||||
0x30cb: 0x04c6, // XK_kana_NI
|
||||
0x30cc: 0x04c7, // XK_kana_NU
|
||||
0x30cd: 0x04c8, // XK_kana_NE
|
||||
0x30ce: 0x04c9, // XK_kana_NO
|
||||
0x30cf: 0x04ca, // XK_kana_HA
|
||||
0x30d2: 0x04cb, // XK_kana_HI
|
||||
0x30d5: 0x04cc, // XK_kana_FU
|
||||
0x30d8: 0x04cd, // XK_kana_HE
|
||||
0x30db: 0x04ce, // XK_kana_HO
|
||||
0x30de: 0x04cf, // XK_kana_MA
|
||||
0x30df: 0x04d0, // XK_kana_MI
|
||||
0x30e0: 0x04d1, // XK_kana_MU
|
||||
0x30e1: 0x04d2, // XK_kana_ME
|
||||
0x30e2: 0x04d3, // XK_kana_MO
|
||||
0x30e3: 0x04ac, // XK_kana_ya
|
||||
0x30e4: 0x04d4, // XK_kana_YA
|
||||
0x30e5: 0x04ad, // XK_kana_yu
|
||||
0x30e6: 0x04d5, // XK_kana_YU
|
||||
0x30e7: 0x04ae, // XK_kana_yo
|
||||
0x30e8: 0x04d6, // XK_kana_YO
|
||||
0x30e9: 0x04d7, // XK_kana_RA
|
||||
0x30ea: 0x04d8, // XK_kana_RI
|
||||
0x30eb: 0x04d9, // XK_kana_RU
|
||||
0x30ec: 0x04da, // XK_kana_RE
|
||||
0x30ed: 0x04db, // XK_kana_RO
|
||||
0x30ef: 0x04dc, // XK_kana_WA
|
||||
0x30f2: 0x04a6, // XK_kana_WO
|
||||
0x30f3: 0x04dd, // XK_kana_N
|
||||
0x30fb: 0x04a5, // XK_kana_conjunctive
|
||||
0x30fc: 0x04b0, // XK_prolongedsound
|
||||
};
|
||||
|
||||
export default {
|
||||
lookup(u) {
|
||||
// Latin-1 is one-to-one mapping
|
||||
if ((u >= 0x20) && (u <= 0xff)) {
|
||||
return u;
|
||||
}
|
||||
|
||||
// Lookup table (fairly random)
|
||||
const keysym = codepoints[u];
|
||||
if (keysym !== undefined) {
|
||||
return keysym;
|
||||
}
|
||||
|
||||
// General mapping as final fallback
|
||||
return 0x01000000 | u;
|
||||
},
|
||||
};
|
276
public/novnc/core/input/mouse.js
Normal file
@ -0,0 +1,276 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
import * as Log from '../util/logging.js';
|
||||
import { isTouchDevice } from '../util/browser.js';
|
||||
import { setCapture, stopEvent, getPointerEvent } from '../util/events.js';
|
||||
|
||||
const WHEEL_STEP = 10; // Delta threshold for a mouse wheel step
|
||||
const WHEEL_STEP_TIMEOUT = 50; // ms
|
||||
const WHEEL_LINE_HEIGHT = 19;
|
||||
|
||||
export default class Mouse {
|
||||
constructor(target) {
|
||||
this._target = target || document;
|
||||
|
||||
this._doubleClickTimer = null;
|
||||
this._lastTouchPos = null;
|
||||
|
||||
this._pos = null;
|
||||
this._wheelStepXTimer = null;
|
||||
this._wheelStepYTimer = null;
|
||||
this._accumulatedWheelDeltaX = 0;
|
||||
this._accumulatedWheelDeltaY = 0;
|
||||
|
||||
this._eventHandlers = {
|
||||
'mousedown': this._handleMouseDown.bind(this),
|
||||
'mouseup': this._handleMouseUp.bind(this),
|
||||
'mousemove': this._handleMouseMove.bind(this),
|
||||
'mousewheel': this._handleMouseWheel.bind(this),
|
||||
'mousedisable': this._handleMouseDisable.bind(this)
|
||||
};
|
||||
|
||||
// ===== PROPERTIES =====
|
||||
|
||||
this.touchButton = 1; // Button mask (1, 2, 4) for touch devices (0 means ignore clicks)
|
||||
|
||||
// ===== EVENT HANDLERS =====
|
||||
|
||||
this.onmousebutton = () => {}; // Handler for mouse button click/release
|
||||
this.onmousemove = () => {}; // Handler for mouse movement
|
||||
}
|
||||
|
||||
// ===== PRIVATE METHODS =====
|
||||
|
||||
_resetDoubleClickTimer() {
|
||||
this._doubleClickTimer = null;
|
||||
}
|
||||
|
||||
_handleMouseButton(e, down) {
|
||||
this._updateMousePosition(e);
|
||||
let pos = this._pos;
|
||||
|
||||
let bmask;
|
||||
if (e.touches || e.changedTouches) {
|
||||
// Touch device
|
||||
|
||||
// When two touches occur within 500 ms of each other and are
|
||||
// close enough together a double click is triggered.
|
||||
if (down == 1) {
|
||||
if (this._doubleClickTimer === null) {
|
||||
this._lastTouchPos = pos;
|
||||
} else {
|
||||
clearTimeout(this._doubleClickTimer);
|
||||
|
||||
// When the distance between the two touches is small enough
|
||||
// force the position of the latter touch to the position of
|
||||
// the first.
|
||||
|
||||
const xs = this._lastTouchPos.x - pos.x;
|
||||
const ys = this._lastTouchPos.y - pos.y;
|
||||
const d = Math.sqrt((xs * xs) + (ys * ys));
|
||||
|
||||
// The goal is to trigger on a certain physical width, the
|
||||
// devicePixelRatio brings us a bit closer but is not optimal.
|
||||
const threshold = 20 * (window.devicePixelRatio || 1);
|
||||
if (d < threshold) {
|
||||
pos = this._lastTouchPos;
|
||||
}
|
||||
}
|
||||
this._doubleClickTimer = setTimeout(this._resetDoubleClickTimer.bind(this), 500);
|
||||
}
|
||||
bmask = this.touchButton;
|
||||
// If bmask is set
|
||||
} else if (e.which) {
|
||||
/* everything except IE */
|
||||
bmask = 1 << e.button;
|
||||
} else {
|
||||
/* IE including 9 */
|
||||
bmask = (e.button & 0x1) + // Left
|
||||
(e.button & 0x2) * 2 + // Right
|
||||
(e.button & 0x4) / 2; // Middle
|
||||
}
|
||||
|
||||
Log.Debug("onmousebutton " + (down ? "down" : "up") +
|
||||
", x: " + pos.x + ", y: " + pos.y + ", bmask: " + bmask);
|
||||
this.onmousebutton(pos.x, pos.y, down, bmask);
|
||||
|
||||
stopEvent(e);
|
||||
}
|
||||
|
||||
_handleMouseDown(e) {
|
||||
// Touch events have implicit capture
|
||||
if (e.type === "mousedown") {
|
||||
setCapture(this._target);
|
||||
}
|
||||
|
||||
this._handleMouseButton(e, 1);
|
||||
}
|
||||
|
||||
_handleMouseUp(e) {
|
||||
this._handleMouseButton(e, 0);
|
||||
}
|
||||
|
||||
// Mouse wheel events are sent in steps over VNC. This means that the VNC
|
||||
// protocol can't handle a wheel event with specific distance or speed.
|
||||
// Therefor, if we get a lot of small mouse wheel events we combine them.
|
||||
_generateWheelStepX() {
|
||||
|
||||
if (this._accumulatedWheelDeltaX < 0) {
|
||||
this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 5);
|
||||
this.onmousebutton(this._pos.x, this._pos.y, 0, 1 << 5);
|
||||
} else if (this._accumulatedWheelDeltaX > 0) {
|
||||
this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 6);
|
||||
this.onmousebutton(this._pos.x, this._pos.y, 0, 1 << 6);
|
||||
}
|
||||
|
||||
this._accumulatedWheelDeltaX = 0;
|
||||
}
|
||||
|
||||
_generateWheelStepY() {
|
||||
|
||||
if (this._accumulatedWheelDeltaY < 0) {
|
||||
this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 3);
|
||||
this.onmousebutton(this._pos.x, this._pos.y, 0, 1 << 3);
|
||||
} else if (this._accumulatedWheelDeltaY > 0) {
|
||||
this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 4);
|
||||
this.onmousebutton(this._pos.x, this._pos.y, 0, 1 << 4);
|
||||
}
|
||||
|
||||
this._accumulatedWheelDeltaY = 0;
|
||||
}
|
||||
|
||||
_resetWheelStepTimers() {
|
||||
window.clearTimeout(this._wheelStepXTimer);
|
||||
window.clearTimeout(this._wheelStepYTimer);
|
||||
this._wheelStepXTimer = null;
|
||||
this._wheelStepYTimer = null;
|
||||
}
|
||||
|
||||
_handleMouseWheel(e) {
|
||||
this._resetWheelStepTimers();
|
||||
|
||||
this._updateMousePosition(e);
|
||||
|
||||
let dX = e.deltaX;
|
||||
let dY = e.deltaY;
|
||||
|
||||
// Pixel units unless it's non-zero.
|
||||
// Note that if deltamode is line or page won't matter since we aren't
|
||||
// sending the mouse wheel delta to the server anyway.
|
||||
// The difference between pixel and line can be important however since
|
||||
// we have a threshold that can be smaller than the line height.
|
||||
if (e.deltaMode !== 0) {
|
||||
dX *= WHEEL_LINE_HEIGHT;
|
||||
dY *= WHEEL_LINE_HEIGHT;
|
||||
}
|
||||
|
||||
this._accumulatedWheelDeltaX += dX;
|
||||
this._accumulatedWheelDeltaY += dY;
|
||||
|
||||
// Generate a mouse wheel step event when the accumulated delta
|
||||
// for one of the axes is large enough.
|
||||
// Small delta events that do not pass the threshold get sent
|
||||
// after a timeout.
|
||||
if (Math.abs(this._accumulatedWheelDeltaX) > WHEEL_STEP) {
|
||||
this._generateWheelStepX();
|
||||
} else {
|
||||
this._wheelStepXTimer =
|
||||
window.setTimeout(this._generateWheelStepX.bind(this),
|
||||
WHEEL_STEP_TIMEOUT);
|
||||
}
|
||||
if (Math.abs(this._accumulatedWheelDeltaY) > WHEEL_STEP) {
|
||||
this._generateWheelStepY();
|
||||
} else {
|
||||
this._wheelStepYTimer =
|
||||
window.setTimeout(this._generateWheelStepY.bind(this),
|
||||
WHEEL_STEP_TIMEOUT);
|
||||
}
|
||||
|
||||
stopEvent(e);
|
||||
}
|
||||
|
||||
_handleMouseMove(e) {
|
||||
this._updateMousePosition(e);
|
||||
this.onmousemove(this._pos.x, this._pos.y);
|
||||
stopEvent(e);
|
||||
}
|
||||
|
||||
_handleMouseDisable(e) {
|
||||
/*
|
||||
* Stop propagation if inside canvas area
|
||||
* Note: This is only needed for the 'click' event as it fails
|
||||
* to fire properly for the target element so we have
|
||||
* to listen on the document element instead.
|
||||
*/
|
||||
if (e.target == this._target) {
|
||||
stopEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Update coordinates relative to target
|
||||
_updateMousePosition(e) {
|
||||
e = getPointerEvent(e);
|
||||
const bounds = this._target.getBoundingClientRect();
|
||||
let x;
|
||||
let y;
|
||||
// Clip to target bounds
|
||||
if (e.clientX < bounds.left) {
|
||||
x = 0;
|
||||
} else if (e.clientX >= bounds.right) {
|
||||
x = bounds.width - 1;
|
||||
} else {
|
||||
x = e.clientX - bounds.left;
|
||||
}
|
||||
if (e.clientY < bounds.top) {
|
||||
y = 0;
|
||||
} else if (e.clientY >= bounds.bottom) {
|
||||
y = bounds.height - 1;
|
||||
} else {
|
||||
y = e.clientY - bounds.top;
|
||||
}
|
||||
this._pos = {x: x, y: y};
|
||||
}
|
||||
|
||||
// ===== PUBLIC METHODS =====
|
||||
|
||||
grab() {
|
||||
if (isTouchDevice) {
|
||||
this._target.addEventListener('touchstart', this._eventHandlers.mousedown);
|
||||
this._target.addEventListener('touchend', this._eventHandlers.mouseup);
|
||||
this._target.addEventListener('touchmove', this._eventHandlers.mousemove);
|
||||
}
|
||||
this._target.addEventListener('mousedown', this._eventHandlers.mousedown);
|
||||
this._target.addEventListener('mouseup', this._eventHandlers.mouseup);
|
||||
this._target.addEventListener('mousemove', this._eventHandlers.mousemove);
|
||||
this._target.addEventListener('wheel', this._eventHandlers.mousewheel);
|
||||
|
||||
/* Prevent middle-click pasting (see above for why we bind to document) */
|
||||
document.addEventListener('click', this._eventHandlers.mousedisable);
|
||||
|
||||
/* preventDefault() on mousedown doesn't stop this event for some
|
||||
reason so we have to explicitly block it */
|
||||
this._target.addEventListener('contextmenu', this._eventHandlers.mousedisable);
|
||||
}
|
||||
|
||||
ungrab() {
|
||||
this._resetWheelStepTimers();
|
||||
|
||||
if (isTouchDevice) {
|
||||
this._target.removeEventListener('touchstart', this._eventHandlers.mousedown);
|
||||
this._target.removeEventListener('touchend', this._eventHandlers.mouseup);
|
||||
this._target.removeEventListener('touchmove', this._eventHandlers.mousemove);
|
||||
}
|
||||
this._target.removeEventListener('mousedown', this._eventHandlers.mousedown);
|
||||
this._target.removeEventListener('mouseup', this._eventHandlers.mouseup);
|
||||
this._target.removeEventListener('mousemove', this._eventHandlers.mousemove);
|
||||
this._target.removeEventListener('wheel', this._eventHandlers.mousewheel);
|
||||
|
||||
document.removeEventListener('click', this._eventHandlers.mousedisable);
|
||||
|
||||
this._target.removeEventListener('contextmenu', this._eventHandlers.mousedisable);
|
||||
}
|
||||
}
|
164
public/novnc/core/input/util.js
Normal file
@ -0,0 +1,164 @@
|
||||
import keysyms from "./keysymdef.js";
|
||||
import vkeys from "./vkeys.js";
|
||||
import fixedkeys from "./fixedkeys.js";
|
||||
import DOMKeyTable from "./domkeytable.js";
|
||||
import * as browser from "../util/browser.js";
|
||||
|
||||
// Get 'KeyboardEvent.code', handling legacy browsers
|
||||
export function getKeycode(evt) {
|
||||
// Are we getting proper key identifiers?
|
||||
// (unfortunately Firefox and Chrome are crappy here and gives
|
||||
// us an empty string on some platforms, rather than leaving it
|
||||
// undefined)
|
||||
if (evt.code) {
|
||||
// Mozilla isn't fully in sync with the spec yet
|
||||
switch (evt.code) {
|
||||
case 'OSLeft': return 'MetaLeft';
|
||||
case 'OSRight': return 'MetaRight';
|
||||
}
|
||||
|
||||
return evt.code;
|
||||
}
|
||||
|
||||
// The de-facto standard is to use Windows Virtual-Key codes
|
||||
// in the 'keyCode' field for non-printable characters. However
|
||||
// Webkit sets it to the same as charCode in 'keypress' events.
|
||||
if ((evt.type !== 'keypress') && (evt.keyCode in vkeys)) {
|
||||
let code = vkeys[evt.keyCode];
|
||||
|
||||
// macOS has messed up this code for some reason
|
||||
if (browser.isMac() && (code === 'ContextMenu')) {
|
||||
code = 'MetaRight';
|
||||
}
|
||||
|
||||
// The keyCode doesn't distinguish between left and right
|
||||
// for the standard modifiers
|
||||
if (evt.location === 2) {
|
||||
switch (code) {
|
||||
case 'ShiftLeft': return 'ShiftRight';
|
||||
case 'ControlLeft': return 'ControlRight';
|
||||
case 'AltLeft': return 'AltRight';
|
||||
}
|
||||
}
|
||||
|
||||
// Nor a bunch of the numpad keys
|
||||
if (evt.location === 3) {
|
||||
switch (code) {
|
||||
case 'Delete': return 'NumpadDecimal';
|
||||
case 'Insert': return 'Numpad0';
|
||||
case 'End': return 'Numpad1';
|
||||
case 'ArrowDown': return 'Numpad2';
|
||||
case 'PageDown': return 'Numpad3';
|
||||
case 'ArrowLeft': return 'Numpad4';
|
||||
case 'ArrowRight': return 'Numpad6';
|
||||
case 'Home': return 'Numpad7';
|
||||
case 'ArrowUp': return 'Numpad8';
|
||||
case 'PageUp': return 'Numpad9';
|
||||
case 'Enter': return 'NumpadEnter';
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
return 'Unidentified';
|
||||
}
|
||||
|
||||
// Get 'KeyboardEvent.key', handling legacy browsers
|
||||
export function getKey(evt) {
|
||||
// Are we getting a proper key value?
|
||||
if (evt.key !== undefined) {
|
||||
// IE and Edge use some ancient version of the spec
|
||||
// https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8860571/
|
||||
switch (evt.key) {
|
||||
case 'Spacebar': return ' ';
|
||||
case 'Esc': return 'Escape';
|
||||
case 'Scroll': return 'ScrollLock';
|
||||
case 'Win': return 'Meta';
|
||||
case 'Apps': return 'ContextMenu';
|
||||
case 'Up': return 'ArrowUp';
|
||||
case 'Left': return 'ArrowLeft';
|
||||
case 'Right': return 'ArrowRight';
|
||||
case 'Down': return 'ArrowDown';
|
||||
case 'Del': return 'Delete';
|
||||
case 'Divide': return '/';
|
||||
case 'Multiply': return '*';
|
||||
case 'Subtract': return '-';
|
||||
case 'Add': return '+';
|
||||
case 'Decimal': return evt.char;
|
||||
}
|
||||
|
||||
// Mozilla isn't fully in sync with the spec yet
|
||||
switch (evt.key) {
|
||||
case 'OS': return 'Meta';
|
||||
}
|
||||
|
||||
// iOS leaks some OS names
|
||||
switch (evt.key) {
|
||||
case 'UIKeyInputUpArrow': return 'ArrowUp';
|
||||
case 'UIKeyInputDownArrow': return 'ArrowDown';
|
||||
case 'UIKeyInputLeftArrow': return 'ArrowLeft';
|
||||
case 'UIKeyInputRightArrow': return 'ArrowRight';
|
||||
case 'UIKeyInputEscape': return 'Escape';
|
||||
}
|
||||
|
||||
// IE and Edge have broken handling of AltGraph so we cannot
|
||||
// trust them for printable characters
|
||||
if ((evt.key.length !== 1) || (!browser.isIE() && !browser.isEdge())) {
|
||||
return evt.key;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to deduce it based on the physical key
|
||||
const code = getKeycode(evt);
|
||||
if (code in fixedkeys) {
|
||||
return fixedkeys[code];
|
||||
}
|
||||
|
||||
// If that failed, then see if we have a printable character
|
||||
if (evt.charCode) {
|
||||
return String.fromCharCode(evt.charCode);
|
||||
}
|
||||
|
||||
// At this point we have nothing left to go on
|
||||
return 'Unidentified';
|
||||
}
|
||||
|
||||
// Get the most reliable keysym value we can get from a key event
|
||||
export function getKeysym(evt) {
|
||||
const key = getKey(evt);
|
||||
|
||||
if (key === 'Unidentified') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// First look up special keys
|
||||
if (key in DOMKeyTable) {
|
||||
let location = evt.location;
|
||||
|
||||
// Safari screws up location for the right cmd key
|
||||
if ((key === 'Meta') && (location === 0)) {
|
||||
location = 2;
|
||||
}
|
||||
|
||||
if ((location === undefined) || (location > 3)) {
|
||||
location = 0;
|
||||
}
|
||||
|
||||
return DOMKeyTable[key][location];
|
||||
}
|
||||
|
||||
// Now we need to look at the Unicode symbol instead
|
||||
|
||||
// Special key? (FIXME: Should have been caught earlier)
|
||||
if (key.length !== 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const codepoint = key.charCodeAt();
|
||||
if (codepoint) {
|
||||
return keysyms.lookup(codepoint);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
117
public/novnc/core/input/vkeys.js
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Mapping between Microsoft® Windows® Virtual-Key codes and
|
||||
* HTML key codes.
|
||||
*/
|
||||
|
||||
export default {
|
||||
0x08: 'Backspace',
|
||||
0x09: 'Tab',
|
||||
0x0a: 'NumpadClear',
|
||||
0x0c: 'Numpad5', // IE11 sends evt.keyCode: 12 when numlock is off
|
||||
0x0d: 'Enter',
|
||||
0x10: 'ShiftLeft',
|
||||
0x11: 'ControlLeft',
|
||||
0x12: 'AltLeft',
|
||||
0x13: 'Pause',
|
||||
0x14: 'CapsLock',
|
||||
0x15: 'Lang1',
|
||||
0x19: 'Lang2',
|
||||
0x1b: 'Escape',
|
||||
0x1c: 'Convert',
|
||||
0x1d: 'NonConvert',
|
||||
0x20: 'Space',
|
||||
0x21: 'PageUp',
|
||||
0x22: 'PageDown',
|
||||
0x23: 'End',
|
||||
0x24: 'Home',
|
||||
0x25: 'ArrowLeft',
|
||||
0x26: 'ArrowUp',
|
||||
0x27: 'ArrowRight',
|
||||
0x28: 'ArrowDown',
|
||||
0x29: 'Select',
|
||||
0x2c: 'PrintScreen',
|
||||
0x2d: 'Insert',
|
||||
0x2e: 'Delete',
|
||||
0x2f: 'Help',
|
||||
0x30: 'Digit0',
|
||||
0x31: 'Digit1',
|
||||
0x32: 'Digit2',
|
||||
0x33: 'Digit3',
|
||||
0x34: 'Digit4',
|
||||
0x35: 'Digit5',
|
||||
0x36: 'Digit6',
|
||||
0x37: 'Digit7',
|
||||
0x38: 'Digit8',
|
||||
0x39: 'Digit9',
|
||||
0x5b: 'MetaLeft',
|
||||
0x5c: 'MetaRight',
|
||||
0x5d: 'ContextMenu',
|
||||
0x5f: 'Sleep',
|
||||
0x60: 'Numpad0',
|
||||
0x61: 'Numpad1',
|
||||
0x62: 'Numpad2',
|
||||
0x63: 'Numpad3',
|
||||
0x64: 'Numpad4',
|
||||
0x65: 'Numpad5',
|
||||
0x66: 'Numpad6',
|
||||
0x67: 'Numpad7',
|
||||
0x68: 'Numpad8',
|
||||
0x69: 'Numpad9',
|
||||
0x6a: 'NumpadMultiply',
|
||||
0x6b: 'NumpadAdd',
|
||||
0x6c: 'NumpadDecimal',
|
||||
0x6d: 'NumpadSubtract',
|
||||
0x6e: 'NumpadDecimal', // Duplicate, because buggy on Windows
|
||||
0x6f: 'NumpadDivide',
|
||||
0x70: 'F1',
|
||||
0x71: 'F2',
|
||||
0x72: 'F3',
|
||||
0x73: 'F4',
|
||||
0x74: 'F5',
|
||||
0x75: 'F6',
|
||||
0x76: 'F7',
|
||||
0x77: 'F8',
|
||||
0x78: 'F9',
|
||||
0x79: 'F10',
|
||||
0x7a: 'F11',
|
||||
0x7b: 'F12',
|
||||
0x7c: 'F13',
|
||||
0x7d: 'F14',
|
||||
0x7e: 'F15',
|
||||
0x7f: 'F16',
|
||||
0x80: 'F17',
|
||||
0x81: 'F18',
|
||||
0x82: 'F19',
|
||||
0x83: 'F20',
|
||||
0x84: 'F21',
|
||||
0x85: 'F22',
|
||||
0x86: 'F23',
|
||||
0x87: 'F24',
|
||||
0x90: 'NumLock',
|
||||
0x91: 'ScrollLock',
|
||||
0xa6: 'BrowserBack',
|
||||
0xa7: 'BrowserForward',
|
||||
0xa8: 'BrowserRefresh',
|
||||
0xa9: 'BrowserStop',
|
||||
0xaa: 'BrowserSearch',
|
||||
0xab: 'BrowserFavorites',
|
||||
0xac: 'BrowserHome',
|
||||
0xad: 'AudioVolumeMute',
|
||||
0xae: 'AudioVolumeDown',
|
||||
0xaf: 'AudioVolumeUp',
|
||||
0xb0: 'MediaTrackNext',
|
||||
0xb1: 'MediaTrackPrevious',
|
||||
0xb2: 'MediaStop',
|
||||
0xb3: 'MediaPlayPause',
|
||||
0xb4: 'LaunchMail',
|
||||
0xb5: 'MediaSelect',
|
||||
0xb6: 'LaunchApp1',
|
||||
0xb7: 'LaunchApp2',
|
||||
0xe1: 'AltRight', // Only when it is AltGraph
|
||||
};
|
171
public/novnc/core/input/xtscancodes.js
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* This file is auto-generated from keymaps.csv on 2017-05-31 16:20
|
||||
* Database checksum sha256(92fd165507f2a3b8c5b3fa56e425d45788dbcb98cf067a307527d91ce22cab94)
|
||||
* To re-generate, run:
|
||||
* keymap-gen --lang=js code-map keymaps.csv html atset1
|
||||
*/
|
||||
export default {
|
||||
"Again": 0xe005, /* html:Again (Again) -> linux:129 (KEY_AGAIN) -> atset1:57349 */
|
||||
"AltLeft": 0x38, /* html:AltLeft (AltLeft) -> linux:56 (KEY_LEFTALT) -> atset1:56 */
|
||||
"AltRight": 0xe038, /* html:AltRight (AltRight) -> linux:100 (KEY_RIGHTALT) -> atset1:57400 */
|
||||
"ArrowDown": 0xe050, /* html:ArrowDown (ArrowDown) -> linux:108 (KEY_DOWN) -> atset1:57424 */
|
||||
"ArrowLeft": 0xe04b, /* html:ArrowLeft (ArrowLeft) -> linux:105 (KEY_LEFT) -> atset1:57419 */
|
||||
"ArrowRight": 0xe04d, /* html:ArrowRight (ArrowRight) -> linux:106 (KEY_RIGHT) -> atset1:57421 */
|
||||
"ArrowUp": 0xe048, /* html:ArrowUp (ArrowUp) -> linux:103 (KEY_UP) -> atset1:57416 */
|
||||
"AudioVolumeDown": 0xe02e, /* html:AudioVolumeDown (AudioVolumeDown) -> linux:114 (KEY_VOLUMEDOWN) -> atset1:57390 */
|
||||
"AudioVolumeMute": 0xe020, /* html:AudioVolumeMute (AudioVolumeMute) -> linux:113 (KEY_MUTE) -> atset1:57376 */
|
||||
"AudioVolumeUp": 0xe030, /* html:AudioVolumeUp (AudioVolumeUp) -> linux:115 (KEY_VOLUMEUP) -> atset1:57392 */
|
||||
"Backquote": 0x29, /* html:Backquote (Backquote) -> linux:41 (KEY_GRAVE) -> atset1:41 */
|
||||
"Backslash": 0x2b, /* html:Backslash (Backslash) -> linux:43 (KEY_BACKSLASH) -> atset1:43 */
|
||||
"Backspace": 0xe, /* html:Backspace (Backspace) -> linux:14 (KEY_BACKSPACE) -> atset1:14 */
|
||||
"BracketLeft": 0x1a, /* html:BracketLeft (BracketLeft) -> linux:26 (KEY_LEFTBRACE) -> atset1:26 */
|
||||
"BracketRight": 0x1b, /* html:BracketRight (BracketRight) -> linux:27 (KEY_RIGHTBRACE) -> atset1:27 */
|
||||
"BrowserBack": 0xe06a, /* html:BrowserBack (BrowserBack) -> linux:158 (KEY_BACK) -> atset1:57450 */
|
||||
"BrowserFavorites": 0xe066, /* html:BrowserFavorites (BrowserFavorites) -> linux:156 (KEY_BOOKMARKS) -> atset1:57446 */
|
||||
"BrowserForward": 0xe069, /* html:BrowserForward (BrowserForward) -> linux:159 (KEY_FORWARD) -> atset1:57449 */
|
||||
"BrowserHome": 0xe032, /* html:BrowserHome (BrowserHome) -> linux:172 (KEY_HOMEPAGE) -> atset1:57394 */
|
||||
"BrowserRefresh": 0xe067, /* html:BrowserRefresh (BrowserRefresh) -> linux:173 (KEY_REFRESH) -> atset1:57447 */
|
||||
"BrowserSearch": 0xe065, /* html:BrowserSearch (BrowserSearch) -> linux:217 (KEY_SEARCH) -> atset1:57445 */
|
||||
"BrowserStop": 0xe068, /* html:BrowserStop (BrowserStop) -> linux:128 (KEY_STOP) -> atset1:57448 */
|
||||
"CapsLock": 0x3a, /* html:CapsLock (CapsLock) -> linux:58 (KEY_CAPSLOCK) -> atset1:58 */
|
||||
"Comma": 0x33, /* html:Comma (Comma) -> linux:51 (KEY_COMMA) -> atset1:51 */
|
||||
"ContextMenu": 0xe05d, /* html:ContextMenu (ContextMenu) -> linux:127 (KEY_COMPOSE) -> atset1:57437 */
|
||||
"ControlLeft": 0x1d, /* html:ControlLeft (ControlLeft) -> linux:29 (KEY_LEFTCTRL) -> atset1:29 */
|
||||
"ControlRight": 0xe01d, /* html:ControlRight (ControlRight) -> linux:97 (KEY_RIGHTCTRL) -> atset1:57373 */
|
||||
"Convert": 0x79, /* html:Convert (Convert) -> linux:92 (KEY_HENKAN) -> atset1:121 */
|
||||
"Copy": 0xe078, /* html:Copy (Copy) -> linux:133 (KEY_COPY) -> atset1:57464 */
|
||||
"Cut": 0xe03c, /* html:Cut (Cut) -> linux:137 (KEY_CUT) -> atset1:57404 */
|
||||
"Delete": 0xe053, /* html:Delete (Delete) -> linux:111 (KEY_DELETE) -> atset1:57427 */
|
||||
"Digit0": 0xb, /* html:Digit0 (Digit0) -> linux:11 (KEY_0) -> atset1:11 */
|
||||
"Digit1": 0x2, /* html:Digit1 (Digit1) -> linux:2 (KEY_1) -> atset1:2 */
|
||||
"Digit2": 0x3, /* html:Digit2 (Digit2) -> linux:3 (KEY_2) -> atset1:3 */
|
||||
"Digit3": 0x4, /* html:Digit3 (Digit3) -> linux:4 (KEY_3) -> atset1:4 */
|
||||
"Digit4": 0x5, /* html:Digit4 (Digit4) -> linux:5 (KEY_4) -> atset1:5 */
|
||||
"Digit5": 0x6, /* html:Digit5 (Digit5) -> linux:6 (KEY_5) -> atset1:6 */
|
||||
"Digit6": 0x7, /* html:Digit6 (Digit6) -> linux:7 (KEY_6) -> atset1:7 */
|
||||
"Digit7": 0x8, /* html:Digit7 (Digit7) -> linux:8 (KEY_7) -> atset1:8 */
|
||||
"Digit8": 0x9, /* html:Digit8 (Digit8) -> linux:9 (KEY_8) -> atset1:9 */
|
||||
"Digit9": 0xa, /* html:Digit9 (Digit9) -> linux:10 (KEY_9) -> atset1:10 */
|
||||
"Eject": 0xe07d, /* html:Eject (Eject) -> linux:162 (KEY_EJECTCLOSECD) -> atset1:57469 */
|
||||
"End": 0xe04f, /* html:End (End) -> linux:107 (KEY_END) -> atset1:57423 */
|
||||
"Enter": 0x1c, /* html:Enter (Enter) -> linux:28 (KEY_ENTER) -> atset1:28 */
|
||||
"Equal": 0xd, /* html:Equal (Equal) -> linux:13 (KEY_EQUAL) -> atset1:13 */
|
||||
"Escape": 0x1, /* html:Escape (Escape) -> linux:1 (KEY_ESC) -> atset1:1 */
|
||||
"F1": 0x3b, /* html:F1 (F1) -> linux:59 (KEY_F1) -> atset1:59 */
|
||||
"F10": 0x44, /* html:F10 (F10) -> linux:68 (KEY_F10) -> atset1:68 */
|
||||
"F11": 0x57, /* html:F11 (F11) -> linux:87 (KEY_F11) -> atset1:87 */
|
||||
"F12": 0x58, /* html:F12 (F12) -> linux:88 (KEY_F12) -> atset1:88 */
|
||||
"F13": 0x5d, /* html:F13 (F13) -> linux:183 (KEY_F13) -> atset1:93 */
|
||||
"F14": 0x5e, /* html:F14 (F14) -> linux:184 (KEY_F14) -> atset1:94 */
|
||||
"F15": 0x5f, /* html:F15 (F15) -> linux:185 (KEY_F15) -> atset1:95 */
|
||||
"F16": 0x55, /* html:F16 (F16) -> linux:186 (KEY_F16) -> atset1:85 */
|
||||
"F17": 0xe003, /* html:F17 (F17) -> linux:187 (KEY_F17) -> atset1:57347 */
|
||||
"F18": 0xe077, /* html:F18 (F18) -> linux:188 (KEY_F18) -> atset1:57463 */
|
||||
"F19": 0xe004, /* html:F19 (F19) -> linux:189 (KEY_F19) -> atset1:57348 */
|
||||
"F2": 0x3c, /* html:F2 (F2) -> linux:60 (KEY_F2) -> atset1:60 */
|
||||
"F20": 0x5a, /* html:F20 (F20) -> linux:190 (KEY_F20) -> atset1:90 */
|
||||
"F21": 0x74, /* html:F21 (F21) -> linux:191 (KEY_F21) -> atset1:116 */
|
||||
"F22": 0xe079, /* html:F22 (F22) -> linux:192 (KEY_F22) -> atset1:57465 */
|
||||
"F23": 0x6d, /* html:F23 (F23) -> linux:193 (KEY_F23) -> atset1:109 */
|
||||
"F24": 0x6f, /* html:F24 (F24) -> linux:194 (KEY_F24) -> atset1:111 */
|
||||
"F3": 0x3d, /* html:F3 (F3) -> linux:61 (KEY_F3) -> atset1:61 */
|
||||
"F4": 0x3e, /* html:F4 (F4) -> linux:62 (KEY_F4) -> atset1:62 */
|
||||
"F5": 0x3f, /* html:F5 (F5) -> linux:63 (KEY_F5) -> atset1:63 */
|
||||
"F6": 0x40, /* html:F6 (F6) -> linux:64 (KEY_F6) -> atset1:64 */
|
||||
"F7": 0x41, /* html:F7 (F7) -> linux:65 (KEY_F7) -> atset1:65 */
|
||||
"F8": 0x42, /* html:F8 (F8) -> linux:66 (KEY_F8) -> atset1:66 */
|
||||
"F9": 0x43, /* html:F9 (F9) -> linux:67 (KEY_F9) -> atset1:67 */
|
||||
"Find": 0xe041, /* html:Find (Find) -> linux:136 (KEY_FIND) -> atset1:57409 */
|
||||
"Help": 0xe075, /* html:Help (Help) -> linux:138 (KEY_HELP) -> atset1:57461 */
|
||||
"Hiragana": 0x77, /* html:Hiragana (Lang4) -> linux:91 (KEY_HIRAGANA) -> atset1:119 */
|
||||
"Home": 0xe047, /* html:Home (Home) -> linux:102 (KEY_HOME) -> atset1:57415 */
|
||||
"Insert": 0xe052, /* html:Insert (Insert) -> linux:110 (KEY_INSERT) -> atset1:57426 */
|
||||
"IntlBackslash": 0x56, /* html:IntlBackslash (IntlBackslash) -> linux:86 (KEY_102ND) -> atset1:86 */
|
||||
"IntlRo": 0x73, /* html:IntlRo (IntlRo) -> linux:89 (KEY_RO) -> atset1:115 */
|
||||
"IntlYen": 0x7d, /* html:IntlYen (IntlYen) -> linux:124 (KEY_YEN) -> atset1:125 */
|
||||
"KanaMode": 0x70, /* html:KanaMode (KanaMode) -> linux:93 (KEY_KATAKANAHIRAGANA) -> atset1:112 */
|
||||
"Katakana": 0x78, /* html:Katakana (Lang3) -> linux:90 (KEY_KATAKANA) -> atset1:120 */
|
||||
"KeyA": 0x1e, /* html:KeyA (KeyA) -> linux:30 (KEY_A) -> atset1:30 */
|
||||
"KeyB": 0x30, /* html:KeyB (KeyB) -> linux:48 (KEY_B) -> atset1:48 */
|
||||
"KeyC": 0x2e, /* html:KeyC (KeyC) -> linux:46 (KEY_C) -> atset1:46 */
|
||||
"KeyD": 0x20, /* html:KeyD (KeyD) -> linux:32 (KEY_D) -> atset1:32 */
|
||||
"KeyE": 0x12, /* html:KeyE (KeyE) -> linux:18 (KEY_E) -> atset1:18 */
|
||||
"KeyF": 0x21, /* html:KeyF (KeyF) -> linux:33 (KEY_F) -> atset1:33 */
|
||||
"KeyG": 0x22, /* html:KeyG (KeyG) -> linux:34 (KEY_G) -> atset1:34 */
|
||||
"KeyH": 0x23, /* html:KeyH (KeyH) -> linux:35 (KEY_H) -> atset1:35 */
|
||||
"KeyI": 0x17, /* html:KeyI (KeyI) -> linux:23 (KEY_I) -> atset1:23 */
|
||||
"KeyJ": 0x24, /* html:KeyJ (KeyJ) -> linux:36 (KEY_J) -> atset1:36 */
|
||||
"KeyK": 0x25, /* html:KeyK (KeyK) -> linux:37 (KEY_K) -> atset1:37 */
|
||||
"KeyL": 0x26, /* html:KeyL (KeyL) -> linux:38 (KEY_L) -> atset1:38 */
|
||||
"KeyM": 0x32, /* html:KeyM (KeyM) -> linux:50 (KEY_M) -> atset1:50 */
|
||||
"KeyN": 0x31, /* html:KeyN (KeyN) -> linux:49 (KEY_N) -> atset1:49 */
|
||||
"KeyO": 0x18, /* html:KeyO (KeyO) -> linux:24 (KEY_O) -> atset1:24 */
|
||||
"KeyP": 0x19, /* html:KeyP (KeyP) -> linux:25 (KEY_P) -> atset1:25 */
|
||||
"KeyQ": 0x10, /* html:KeyQ (KeyQ) -> linux:16 (KEY_Q) -> atset1:16 */
|
||||
"KeyR": 0x13, /* html:KeyR (KeyR) -> linux:19 (KEY_R) -> atset1:19 */
|
||||
"KeyS": 0x1f, /* html:KeyS (KeyS) -> linux:31 (KEY_S) -> atset1:31 */
|
||||
"KeyT": 0x14, /* html:KeyT (KeyT) -> linux:20 (KEY_T) -> atset1:20 */
|
||||
"KeyU": 0x16, /* html:KeyU (KeyU) -> linux:22 (KEY_U) -> atset1:22 */
|
||||
"KeyV": 0x2f, /* html:KeyV (KeyV) -> linux:47 (KEY_V) -> atset1:47 */
|
||||
"KeyW": 0x11, /* html:KeyW (KeyW) -> linux:17 (KEY_W) -> atset1:17 */
|
||||
"KeyX": 0x2d, /* html:KeyX (KeyX) -> linux:45 (KEY_X) -> atset1:45 */
|
||||
"KeyY": 0x15, /* html:KeyY (KeyY) -> linux:21 (KEY_Y) -> atset1:21 */
|
||||
"KeyZ": 0x2c, /* html:KeyZ (KeyZ) -> linux:44 (KEY_Z) -> atset1:44 */
|
||||
"Lang3": 0x78, /* html:Lang3 (Lang3) -> linux:90 (KEY_KATAKANA) -> atset1:120 */
|
||||
"Lang4": 0x77, /* html:Lang4 (Lang4) -> linux:91 (KEY_HIRAGANA) -> atset1:119 */
|
||||
"Lang5": 0x76, /* html:Lang5 (Lang5) -> linux:85 (KEY_ZENKAKUHANKAKU) -> atset1:118 */
|
||||
"LaunchApp1": 0xe06b, /* html:LaunchApp1 (LaunchApp1) -> linux:157 (KEY_COMPUTER) -> atset1:57451 */
|
||||
"LaunchApp2": 0xe021, /* html:LaunchApp2 (LaunchApp2) -> linux:140 (KEY_CALC) -> atset1:57377 */
|
||||
"LaunchMail": 0xe06c, /* html:LaunchMail (LaunchMail) -> linux:155 (KEY_MAIL) -> atset1:57452 */
|
||||
"MediaPlayPause": 0xe022, /* html:MediaPlayPause (MediaPlayPause) -> linux:164 (KEY_PLAYPAUSE) -> atset1:57378 */
|
||||
"MediaSelect": 0xe06d, /* html:MediaSelect (MediaSelect) -> linux:226 (KEY_MEDIA) -> atset1:57453 */
|
||||
"MediaStop": 0xe024, /* html:MediaStop (MediaStop) -> linux:166 (KEY_STOPCD) -> atset1:57380 */
|
||||
"MediaTrackNext": 0xe019, /* html:MediaTrackNext (MediaTrackNext) -> linux:163 (KEY_NEXTSONG) -> atset1:57369 */
|
||||
"MediaTrackPrevious": 0xe010, /* html:MediaTrackPrevious (MediaTrackPrevious) -> linux:165 (KEY_PREVIOUSSONG) -> atset1:57360 */
|
||||
"MetaLeft": 0xe05b, /* html:MetaLeft (MetaLeft) -> linux:125 (KEY_LEFTMETA) -> atset1:57435 */
|
||||
"MetaRight": 0xe05c, /* html:MetaRight (MetaRight) -> linux:126 (KEY_RIGHTMETA) -> atset1:57436 */
|
||||
"Minus": 0xc, /* html:Minus (Minus) -> linux:12 (KEY_MINUS) -> atset1:12 */
|
||||
"NonConvert": 0x7b, /* html:NonConvert (NonConvert) -> linux:94 (KEY_MUHENKAN) -> atset1:123 */
|
||||
"NumLock": 0x45, /* html:NumLock (NumLock) -> linux:69 (KEY_NUMLOCK) -> atset1:69 */
|
||||
"Numpad0": 0x52, /* html:Numpad0 (Numpad0) -> linux:82 (KEY_KP0) -> atset1:82 */
|
||||
"Numpad1": 0x4f, /* html:Numpad1 (Numpad1) -> linux:79 (KEY_KP1) -> atset1:79 */
|
||||
"Numpad2": 0x50, /* html:Numpad2 (Numpad2) -> linux:80 (KEY_KP2) -> atset1:80 */
|
||||
"Numpad3": 0x51, /* html:Numpad3 (Numpad3) -> linux:81 (KEY_KP3) -> atset1:81 */
|
||||
"Numpad4": 0x4b, /* html:Numpad4 (Numpad4) -> linux:75 (KEY_KP4) -> atset1:75 */
|
||||
"Numpad5": 0x4c, /* html:Numpad5 (Numpad5) -> linux:76 (KEY_KP5) -> atset1:76 */
|
||||
"Numpad6": 0x4d, /* html:Numpad6 (Numpad6) -> linux:77 (KEY_KP6) -> atset1:77 */
|
||||
"Numpad7": 0x47, /* html:Numpad7 (Numpad7) -> linux:71 (KEY_KP7) -> atset1:71 */
|
||||
"Numpad8": 0x48, /* html:Numpad8 (Numpad8) -> linux:72 (KEY_KP8) -> atset1:72 */
|
||||
"Numpad9": 0x49, /* html:Numpad9 (Numpad9) -> linux:73 (KEY_KP9) -> atset1:73 */
|
||||
"NumpadAdd": 0x4e, /* html:NumpadAdd (NumpadAdd) -> linux:78 (KEY_KPPLUS) -> atset1:78 */
|
||||
"NumpadComma": 0x7e, /* html:NumpadComma (NumpadComma) -> linux:121 (KEY_KPCOMMA) -> atset1:126 */
|
||||
"NumpadDecimal": 0x53, /* html:NumpadDecimal (NumpadDecimal) -> linux:83 (KEY_KPDOT) -> atset1:83 */
|
||||
"NumpadDivide": 0xe035, /* html:NumpadDivide (NumpadDivide) -> linux:98 (KEY_KPSLASH) -> atset1:57397 */
|
||||
"NumpadEnter": 0xe01c, /* html:NumpadEnter (NumpadEnter) -> linux:96 (KEY_KPENTER) -> atset1:57372 */
|
||||
"NumpadEqual": 0x59, /* html:NumpadEqual (NumpadEqual) -> linux:117 (KEY_KPEQUAL) -> atset1:89 */
|
||||
"NumpadMultiply": 0x37, /* html:NumpadMultiply (NumpadMultiply) -> linux:55 (KEY_KPASTERISK) -> atset1:55 */
|
||||
"NumpadParenLeft": 0xe076, /* html:NumpadParenLeft (NumpadParenLeft) -> linux:179 (KEY_KPLEFTPAREN) -> atset1:57462 */
|
||||
"NumpadParenRight": 0xe07b, /* html:NumpadParenRight (NumpadParenRight) -> linux:180 (KEY_KPRIGHTPAREN) -> atset1:57467 */
|
||||
"NumpadSubtract": 0x4a, /* html:NumpadSubtract (NumpadSubtract) -> linux:74 (KEY_KPMINUS) -> atset1:74 */
|
||||
"Open": 0x64, /* html:Open (Open) -> linux:134 (KEY_OPEN) -> atset1:100 */
|
||||
"PageDown": 0xe051, /* html:PageDown (PageDown) -> linux:109 (KEY_PAGEDOWN) -> atset1:57425 */
|
||||
"PageUp": 0xe049, /* html:PageUp (PageUp) -> linux:104 (KEY_PAGEUP) -> atset1:57417 */
|
||||
"Paste": 0x65, /* html:Paste (Paste) -> linux:135 (KEY_PASTE) -> atset1:101 */
|
||||
"Pause": 0xe046, /* html:Pause (Pause) -> linux:119 (KEY_PAUSE) -> atset1:57414 */
|
||||
"Period": 0x34, /* html:Period (Period) -> linux:52 (KEY_DOT) -> atset1:52 */
|
||||
"Power": 0xe05e, /* html:Power (Power) -> linux:116 (KEY_POWER) -> atset1:57438 */
|
||||
"PrintScreen": 0x54, /* html:PrintScreen (PrintScreen) -> linux:99 (KEY_SYSRQ) -> atset1:84 */
|
||||
"Props": 0xe006, /* html:Props (Props) -> linux:130 (KEY_PROPS) -> atset1:57350 */
|
||||
"Quote": 0x28, /* html:Quote (Quote) -> linux:40 (KEY_APOSTROPHE) -> atset1:40 */
|
||||
"ScrollLock": 0x46, /* html:ScrollLock (ScrollLock) -> linux:70 (KEY_SCROLLLOCK) -> atset1:70 */
|
||||
"Semicolon": 0x27, /* html:Semicolon (Semicolon) -> linux:39 (KEY_SEMICOLON) -> atset1:39 */
|
||||
"ShiftLeft": 0x2a, /* html:ShiftLeft (ShiftLeft) -> linux:42 (KEY_LEFTSHIFT) -> atset1:42 */
|
||||
"ShiftRight": 0x36, /* html:ShiftRight (ShiftRight) -> linux:54 (KEY_RIGHTSHIFT) -> atset1:54 */
|
||||
"Slash": 0x35, /* html:Slash (Slash) -> linux:53 (KEY_SLASH) -> atset1:53 */
|
||||
"Sleep": 0xe05f, /* html:Sleep (Sleep) -> linux:142 (KEY_SLEEP) -> atset1:57439 */
|
||||
"Space": 0x39, /* html:Space (Space) -> linux:57 (KEY_SPACE) -> atset1:57 */
|
||||
"Suspend": 0xe025, /* html:Suspend (Suspend) -> linux:205 (KEY_SUSPEND) -> atset1:57381 */
|
||||
"Tab": 0xf, /* html:Tab (Tab) -> linux:15 (KEY_TAB) -> atset1:15 */
|
||||
"Undo": 0xe007, /* html:Undo (Undo) -> linux:131 (KEY_UNDO) -> atset1:57351 */
|
||||
"WakeUp": 0xe063, /* html:WakeUp (WakeUp) -> linux:143 (KEY_WAKEUP) -> atset1:57443 */
|
||||
};
|
2055
public/novnc/core/rfb.js
Normal file
90
public/novnc/core/util/browser.js
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*/
|
||||
|
||||
import * as Log from './logging.js';
|
||||
|
||||
// Touch detection
|
||||
export let isTouchDevice = ('ontouchstart' in document.documentElement) ||
|
||||
// requried for Chrome debugger
|
||||
(document.ontouchstart !== undefined) ||
|
||||
// required for MS Surface
|
||||
(navigator.maxTouchPoints > 0) ||
|
||||
(navigator.msMaxTouchPoints > 0);
|
||||
window.addEventListener('touchstart', function onFirstTouch() {
|
||||
isTouchDevice = true;
|
||||
window.removeEventListener('touchstart', onFirstTouch, false);
|
||||
}, false);
|
||||
|
||||
|
||||
// The goal is to find a certain physical width, the devicePixelRatio
|
||||
// brings us a bit closer but is not optimal.
|
||||
export let dragThreshold = 10 * (window.devicePixelRatio || 1);
|
||||
|
||||
let _supportsCursorURIs = false;
|
||||
|
||||
try {
|
||||
const target = document.createElement('canvas');
|
||||
target.style.cursor = 'url("data:image/x-icon;base64,AAACAAEACAgAAAIAAgA4AQAAFgAAACgAAAAIAAAAEAAAAAEAIAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAA==") 2 2, default';
|
||||
|
||||
if (target.style.cursor) {
|
||||
Log.Info("Data URI scheme cursor supported");
|
||||
_supportsCursorURIs = true;
|
||||
} else {
|
||||
Log.Warn("Data URI scheme cursor not supported");
|
||||
}
|
||||
} catch (exc) {
|
||||
Log.Error("Data URI scheme cursor test exception: " + exc);
|
||||
}
|
||||
|
||||
export const supportsCursorURIs = _supportsCursorURIs;
|
||||
|
||||
let _supportsImageMetadata = false;
|
||||
try {
|
||||
new ImageData(new Uint8ClampedArray(4), 1, 1);
|
||||
_supportsImageMetadata = true;
|
||||
} catch (ex) {
|
||||
// ignore failure
|
||||
}
|
||||
export const supportsImageMetadata = _supportsImageMetadata;
|
||||
|
||||
export function isMac() {
|
||||
return navigator && !!(/mac/i).exec(navigator.platform);
|
||||
}
|
||||
|
||||
export function isWindows() {
|
||||
return navigator && !!(/win/i).exec(navigator.platform);
|
||||
}
|
||||
|
||||
export function isIOS() {
|
||||
return navigator &&
|
||||
(!!(/ipad/i).exec(navigator.platform) ||
|
||||
!!(/iphone/i).exec(navigator.platform) ||
|
||||
!!(/ipod/i).exec(navigator.platform));
|
||||
}
|
||||
|
||||
export function isAndroid() {
|
||||
return navigator && !!(/android/i).exec(navigator.userAgent);
|
||||
}
|
||||
|
||||
export function isSafari() {
|
||||
return navigator && (navigator.userAgent.indexOf('Safari') !== -1 &&
|
||||
navigator.userAgent.indexOf('Chrome') === -1);
|
||||
}
|
||||
|
||||
export function isIE() {
|
||||
return navigator && !!(/trident/i).exec(navigator.userAgent);
|
||||
}
|
||||
|
||||
export function isEdge() {
|
||||
return navigator && !!(/edge/i).exec(navigator.userAgent);
|
||||
}
|
||||
|
||||
export function isFirefox() {
|
||||
return navigator && !!(/firefox/i).exec(navigator.userAgent);
|
||||
}
|
||||
|
221
public/novnc/core/util/cursor.js
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
import { supportsCursorURIs, isTouchDevice } from './browser.js';
|
||||
|
||||
const useFallback = !supportsCursorURIs || isTouchDevice;
|
||||
|
||||
export default class Cursor {
|
||||
constructor() {
|
||||
this._target = null;
|
||||
|
||||
this._canvas = document.createElement('canvas');
|
||||
|
||||
if (useFallback) {
|
||||
this._canvas.style.position = 'fixed';
|
||||
this._canvas.style.zIndex = '65535';
|
||||
this._canvas.style.pointerEvents = 'none';
|
||||
// Can't use "display" because of Firefox bug #1445997
|
||||
this._canvas.style.visibility = 'hidden';
|
||||
document.body.appendChild(this._canvas);
|
||||
}
|
||||
|
||||
this._position = { x: 0, y: 0 };
|
||||
this._hotSpot = { x: 0, y: 0 };
|
||||
|
||||
this._eventHandlers = {
|
||||
'mouseover': this._handleMouseOver.bind(this),
|
||||
'mouseleave': this._handleMouseLeave.bind(this),
|
||||
'mousemove': this._handleMouseMove.bind(this),
|
||||
'mouseup': this._handleMouseUp.bind(this),
|
||||
'touchstart': this._handleTouchStart.bind(this),
|
||||
'touchmove': this._handleTouchMove.bind(this),
|
||||
'touchend': this._handleTouchEnd.bind(this),
|
||||
};
|
||||
}
|
||||
|
||||
attach(target) {
|
||||
if (this._target) {
|
||||
this.detach();
|
||||
}
|
||||
|
||||
this._target = target;
|
||||
|
||||
if (useFallback) {
|
||||
// FIXME: These don't fire properly except for mouse
|
||||
/// movement in IE. We want to also capture element
|
||||
// movement, size changes, visibility, etc.
|
||||
const options = { capture: true, passive: true };
|
||||
this._target.addEventListener('mouseover', this._eventHandlers.mouseover, options);
|
||||
this._target.addEventListener('mouseleave', this._eventHandlers.mouseleave, options);
|
||||
this._target.addEventListener('mousemove', this._eventHandlers.mousemove, options);
|
||||
this._target.addEventListener('mouseup', this._eventHandlers.mouseup, options);
|
||||
|
||||
// There is no "touchleave" so we monitor touchstart globally
|
||||
window.addEventListener('touchstart', this._eventHandlers.touchstart, options);
|
||||
this._target.addEventListener('touchmove', this._eventHandlers.touchmove, options);
|
||||
this._target.addEventListener('touchend', this._eventHandlers.touchend, options);
|
||||
}
|
||||
|
||||
this.clear();
|
||||
}
|
||||
|
||||
detach() {
|
||||
if (useFallback) {
|
||||
const options = { capture: true, passive: true };
|
||||
this._target.removeEventListener('mouseover', this._eventHandlers.mouseover, options);
|
||||
this._target.removeEventListener('mouseleave', this._eventHandlers.mouseleave, options);
|
||||
this._target.removeEventListener('mousemove', this._eventHandlers.mousemove, options);
|
||||
this._target.removeEventListener('mouseup', this._eventHandlers.mouseup, options);
|
||||
|
||||
window.removeEventListener('touchstart', this._eventHandlers.touchstart, options);
|
||||
this._target.removeEventListener('touchmove', this._eventHandlers.touchmove, options);
|
||||
this._target.removeEventListener('touchend', this._eventHandlers.touchend, options);
|
||||
}
|
||||
|
||||
this._target = null;
|
||||
}
|
||||
|
||||
change(rgba, hotx, hoty, w, h) {
|
||||
if ((w === 0) || (h === 0)) {
|
||||
this.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
this._position.x = this._position.x + this._hotSpot.x - hotx;
|
||||
this._position.y = this._position.y + this._hotSpot.y - hoty;
|
||||
this._hotSpot.x = hotx;
|
||||
this._hotSpot.y = hoty;
|
||||
|
||||
let ctx = this._canvas.getContext('2d');
|
||||
|
||||
this._canvas.width = w;
|
||||
this._canvas.height = h;
|
||||
|
||||
let img;
|
||||
try {
|
||||
// IE doesn't support this
|
||||
img = new ImageData(new Uint8ClampedArray(rgba), w, h);
|
||||
} catch (ex) {
|
||||
img = ctx.createImageData(w, h);
|
||||
img.data.set(new Uint8ClampedArray(rgba));
|
||||
}
|
||||
ctx.clearRect(0, 0, w, h);
|
||||
ctx.putImageData(img, 0, 0);
|
||||
|
||||
if (useFallback) {
|
||||
this._updatePosition();
|
||||
} else {
|
||||
let url = this._canvas.toDataURL();
|
||||
this._target.style.cursor = 'url(' + url + ')' + hotx + ' ' + hoty + ', default';
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
this._target.style.cursor = 'none';
|
||||
this._canvas.width = 0;
|
||||
this._canvas.height = 0;
|
||||
this._position.x = this._position.x + this._hotSpot.x;
|
||||
this._position.y = this._position.y + this._hotSpot.y;
|
||||
this._hotSpot.x = 0;
|
||||
this._hotSpot.y = 0;
|
||||
}
|
||||
|
||||
_handleMouseOver(event) {
|
||||
// This event could be because we're entering the target, or
|
||||
// moving around amongst its sub elements. Let the move handler
|
||||
// sort things out.
|
||||
this._handleMouseMove(event);
|
||||
}
|
||||
|
||||
_handleMouseLeave(event) {
|
||||
this._hideCursor();
|
||||
}
|
||||
|
||||
_handleMouseMove(event) {
|
||||
this._updateVisibility(event.target);
|
||||
|
||||
this._position.x = event.clientX - this._hotSpot.x;
|
||||
this._position.y = event.clientY - this._hotSpot.y;
|
||||
|
||||
this._updatePosition();
|
||||
}
|
||||
|
||||
_handleMouseUp(event) {
|
||||
// We might get this event because of a drag operation that
|
||||
// moved outside of the target. Check what's under the cursor
|
||||
// now and adjust visibility based on that.
|
||||
let target = document.elementFromPoint(event.clientX, event.clientY);
|
||||
this._updateVisibility(target);
|
||||
}
|
||||
|
||||
_handleTouchStart(event) {
|
||||
// Just as for mouseover, we let the move handler deal with it
|
||||
this._handleTouchMove(event);
|
||||
}
|
||||
|
||||
_handleTouchMove(event) {
|
||||
this._updateVisibility(event.target);
|
||||
|
||||
this._position.x = event.changedTouches[0].clientX - this._hotSpot.x;
|
||||
this._position.y = event.changedTouches[0].clientY - this._hotSpot.y;
|
||||
|
||||
this._updatePosition();
|
||||
}
|
||||
|
||||
_handleTouchEnd(event) {
|
||||
// Same principle as for mouseup
|
||||
let target = document.elementFromPoint(event.changedTouches[0].clientX,
|
||||
event.changedTouches[0].clientY);
|
||||
this._updateVisibility(target);
|
||||
}
|
||||
|
||||
_showCursor() {
|
||||
if (this._canvas.style.visibility === 'hidden') {
|
||||
this._canvas.style.visibility = '';
|
||||
}
|
||||
}
|
||||
|
||||
_hideCursor() {
|
||||
if (this._canvas.style.visibility !== 'hidden') {
|
||||
this._canvas.style.visibility = 'hidden';
|
||||
}
|
||||
}
|
||||
|
||||
// Should we currently display the cursor?
|
||||
// (i.e. are we over the target, or a child of the target without a
|
||||
// different cursor set)
|
||||
_shouldShowCursor(target) {
|
||||
// Easy case
|
||||
if (target === this._target) {
|
||||
return true;
|
||||
}
|
||||
// Other part of the DOM?
|
||||
if (!this._target.contains(target)) {
|
||||
return false;
|
||||
}
|
||||
// Has the child its own cursor?
|
||||
// FIXME: How can we tell that a sub element has an
|
||||
// explicit "cursor: none;"?
|
||||
if (window.getComputedStyle(target).cursor !== 'none') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
_updateVisibility(target) {
|
||||
if (this._shouldShowCursor(target)) {
|
||||
this._showCursor();
|
||||
} else {
|
||||
this._hideCursor();
|
||||
}
|
||||
}
|
||||
|
||||
_updatePosition() {
|
||||
this._canvas.style.left = this._position.x + "px";
|
||||
this._canvas.style.top = this._position.y + "px";
|
||||
}
|
||||
}
|
139
public/novnc/core/util/events.js
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Cross-browser event and position routines
|
||||
*/
|
||||
|
||||
export function getPointerEvent(e) {
|
||||
return e.changedTouches ? e.changedTouches[0] : e.touches ? e.touches[0] : e;
|
||||
}
|
||||
|
||||
export function stopEvent(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
// Emulate Element.setCapture() when not supported
|
||||
let _captureRecursion = false;
|
||||
let _captureElem = null;
|
||||
function _captureProxy(e) {
|
||||
// Recursion protection as we'll see our own event
|
||||
if (_captureRecursion) return;
|
||||
|
||||
// Clone the event as we cannot dispatch an already dispatched event
|
||||
const newEv = new e.constructor(e.type, e);
|
||||
|
||||
_captureRecursion = true;
|
||||
_captureElem.dispatchEvent(newEv);
|
||||
_captureRecursion = false;
|
||||
|
||||
// Avoid double events
|
||||
e.stopPropagation();
|
||||
|
||||
// Respect the wishes of the redirected event handlers
|
||||
if (newEv.defaultPrevented) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
// Implicitly release the capture on button release
|
||||
if (e.type === "mouseup") {
|
||||
releaseCapture();
|
||||
}
|
||||
}
|
||||
|
||||
// Follow cursor style of target element
|
||||
function _captureElemChanged() {
|
||||
const captureElem = document.getElementById("noVNC_mouse_capture_elem");
|
||||
captureElem.style.cursor = window.getComputedStyle(_captureElem).cursor;
|
||||
}
|
||||
|
||||
const _captureObserver = new MutationObserver(_captureElemChanged);
|
||||
|
||||
let _captureIndex = 0;
|
||||
|
||||
export function setCapture(elem) {
|
||||
if (elem.setCapture) {
|
||||
|
||||
elem.setCapture();
|
||||
|
||||
// IE releases capture on 'click' events which might not trigger
|
||||
elem.addEventListener('mouseup', releaseCapture);
|
||||
|
||||
} else {
|
||||
// Release any existing capture in case this method is
|
||||
// called multiple times without coordination
|
||||
releaseCapture();
|
||||
|
||||
let captureElem = document.getElementById("noVNC_mouse_capture_elem");
|
||||
|
||||
if (captureElem === null) {
|
||||
captureElem = document.createElement("div");
|
||||
captureElem.id = "noVNC_mouse_capture_elem";
|
||||
captureElem.style.position = "fixed";
|
||||
captureElem.style.top = "0px";
|
||||
captureElem.style.left = "0px";
|
||||
captureElem.style.width = "100%";
|
||||
captureElem.style.height = "100%";
|
||||
captureElem.style.zIndex = 10000;
|
||||
captureElem.style.display = "none";
|
||||
document.body.appendChild(captureElem);
|
||||
|
||||
// This is to make sure callers don't get confused by having
|
||||
// our blocking element as the target
|
||||
captureElem.addEventListener('contextmenu', _captureProxy);
|
||||
|
||||
captureElem.addEventListener('mousemove', _captureProxy);
|
||||
captureElem.addEventListener('mouseup', _captureProxy);
|
||||
}
|
||||
|
||||
_captureElem = elem;
|
||||
_captureIndex++;
|
||||
|
||||
// Track cursor and get initial cursor
|
||||
_captureObserver.observe(elem, {attributes: true});
|
||||
_captureElemChanged();
|
||||
|
||||
captureElem.style.display = "";
|
||||
|
||||
// We listen to events on window in order to keep tracking if it
|
||||
// happens to leave the viewport
|
||||
window.addEventListener('mousemove', _captureProxy);
|
||||
window.addEventListener('mouseup', _captureProxy);
|
||||
}
|
||||
}
|
||||
|
||||
export function releaseCapture() {
|
||||
if (document.releaseCapture) {
|
||||
|
||||
document.releaseCapture();
|
||||
|
||||
} else {
|
||||
if (!_captureElem) {
|
||||
return;
|
||||
}
|
||||
|
||||
// There might be events already queued, so we need to wait for
|
||||
// them to flush. E.g. contextmenu in Microsoft Edge
|
||||
window.setTimeout((expected) => {
|
||||
// Only clear it if it's the expected grab (i.e. no one
|
||||
// else has initiated a new grab)
|
||||
if (_captureIndex === expected) {
|
||||
_captureElem = null;
|
||||
}
|
||||
}, 0, _captureIndex);
|
||||
|
||||
_captureObserver.disconnect();
|
||||
|
||||
const captureElem = document.getElementById("noVNC_mouse_capture_elem");
|
||||
captureElem.style.display = "none";
|
||||
|
||||
window.removeEventListener('mousemove', _captureProxy);
|
||||
window.removeEventListener('mouseup', _captureProxy);
|
||||
}
|
||||
}
|
35
public/novnc/core/util/eventtarget.js
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*/
|
||||
|
||||
export default class EventTargetMixin {
|
||||
constructor() {
|
||||
this._listeners = new Map();
|
||||
}
|
||||
|
||||
addEventListener(type, callback) {
|
||||
if (!this._listeners.has(type)) {
|
||||
this._listeners.set(type, new Set());
|
||||
}
|
||||
this._listeners.get(type).add(callback);
|
||||
}
|
||||
|
||||
removeEventListener(type, callback) {
|
||||
if (this._listeners.has(type)) {
|
||||
this._listeners.get(type).delete(callback);
|
||||
}
|
||||
}
|
||||
|
||||
dispatchEvent(event) {
|
||||
if (!this._listeners.has(event.type)) {
|
||||
return true;
|
||||
}
|
||||
this._listeners.get(event.type)
|
||||
.forEach(callback => callback.call(this, event));
|
||||
return !event.defaultPrevented;
|
||||
}
|
||||
}
|
56
public/novnc/core/util/logging.js
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Logging/debug routines
|
||||
*/
|
||||
|
||||
let _log_level = 'warn';
|
||||
|
||||
let Debug = () => {};
|
||||
let Info = () => {};
|
||||
let Warn = () => {};
|
||||
let Error = () => {};
|
||||
|
||||
export function init_logging(level) {
|
||||
if (typeof level === 'undefined') {
|
||||
level = _log_level;
|
||||
} else {
|
||||
_log_level = level;
|
||||
}
|
||||
|
||||
Debug = Info = Warn = Error = () => {};
|
||||
|
||||
if (typeof window.console !== "undefined") {
|
||||
/* eslint-disable no-console, no-fallthrough */
|
||||
switch (level) {
|
||||
case 'debug':
|
||||
Debug = console.debug.bind(window.console);
|
||||
case 'info':
|
||||
Info = console.info.bind(window.console);
|
||||
case 'warn':
|
||||
Warn = console.warn.bind(window.console);
|
||||
case 'error':
|
||||
Error = console.error.bind(window.console);
|
||||
case 'none':
|
||||
break;
|
||||
default:
|
||||
throw new window.Error("invalid logging type '" + level + "'");
|
||||
}
|
||||
/* eslint-enable no-console, no-fallthrough */
|
||||
}
|
||||
}
|
||||
|
||||
export function get_logging() {
|
||||
return _log_level;
|
||||
}
|
||||
|
||||
export { Debug, Info, Warn, Error };
|
||||
|
||||
// Initialize logging level
|
||||
init_logging();
|
54
public/novnc/core/util/polyfill.js
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
/* Polyfills to provide new APIs in old browsers */
|
||||
|
||||
/* Object.assign() (taken from MDN) */
|
||||
if (typeof Object.assign != 'function') {
|
||||
// Must be writable: true, enumerable: false, configurable: true
|
||||
Object.defineProperty(Object, "assign", {
|
||||
value: function assign(target, varArgs) { // .length of function is 2
|
||||
'use strict';
|
||||
if (target == null) { // TypeError if undefined or null
|
||||
throw new TypeError('Cannot convert undefined or null to object');
|
||||
}
|
||||
|
||||
const to = Object(target);
|
||||
|
||||
for (let index = 1; index < arguments.length; index++) {
|
||||
const nextSource = arguments[index];
|
||||
|
||||
if (nextSource != null) { // Skip over if undefined or null
|
||||
for (let nextKey in nextSource) {
|
||||
// Avoid bugs when hasOwnProperty is shadowed
|
||||
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
|
||||
to[nextKey] = nextSource[nextKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return to;
|
||||
},
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
|
||||
/* CustomEvent constructor (taken from MDN) */
|
||||
(() => {
|
||||
function CustomEvent(event, params) {
|
||||
params = params || { bubbles: false, cancelable: false, detail: undefined };
|
||||
const evt = document.createEvent( 'CustomEvent' );
|
||||
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
|
||||
return evt;
|
||||
}
|
||||
|
||||
CustomEvent.prototype = window.Event.prototype;
|
||||
|
||||
if (typeof window.CustomEvent !== "function") {
|
||||
window.CustomEvent = CustomEvent;
|
||||
}
|
||||
})();
|
14
public/novnc/core/util/strings.js
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Decode from UTF-8
|
||||
*/
|
||||
export function decodeUTF8(utf8string) {
|
||||
return decodeURIComponent(escape(utf8string));
|
||||
}
|
290
public/novnc/core/websock.js
Normal file
@ -0,0 +1,290 @@
|
||||
/*
|
||||
* Websock: high-performance binary WebSockets
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* Websock is similar to the standard WebSocket object but with extra
|
||||
* buffer handling.
|
||||
*
|
||||
* Websock has built-in receive queue buffering; the message event
|
||||
* does not contain actual data but is simply a notification that
|
||||
* there is new data available. Several rQ* methods are available to
|
||||
* read binary data off of the receive queue.
|
||||
*/
|
||||
|
||||
import * as Log from './util/logging.js';
|
||||
|
||||
// this has performance issues in some versions Chromium, and
|
||||
// doesn't gain a tremendous amount of performance increase in Firefox
|
||||
// at the moment. It may be valuable to turn it on in the future.
|
||||
const ENABLE_COPYWITHIN = false;
|
||||
const MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB
|
||||
|
||||
export default class Websock {
|
||||
constructor() {
|
||||
this._websocket = null; // WebSocket object
|
||||
|
||||
this._rQi = 0; // Receive queue index
|
||||
this._rQlen = 0; // Next write position in the receive queue
|
||||
this._rQbufferSize = 1024 * 1024 * 4; // Receive queue buffer size (4 MiB)
|
||||
this._rQmax = this._rQbufferSize / 8;
|
||||
// called in init: this._rQ = new Uint8Array(this._rQbufferSize);
|
||||
this._rQ = null; // Receive queue
|
||||
|
||||
this._sQbufferSize = 1024 * 10; // 10 KiB
|
||||
// called in init: this._sQ = new Uint8Array(this._sQbufferSize);
|
||||
this._sQlen = 0;
|
||||
this._sQ = null; // Send queue
|
||||
|
||||
this._eventHandlers = {
|
||||
message: () => {},
|
||||
open: () => {},
|
||||
close: () => {},
|
||||
error: () => {}
|
||||
};
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
get sQ() {
|
||||
return this._sQ;
|
||||
}
|
||||
|
||||
get rQ() {
|
||||
return this._rQ;
|
||||
}
|
||||
|
||||
get rQi() {
|
||||
return this._rQi;
|
||||
}
|
||||
|
||||
set rQi(val) {
|
||||
this._rQi = val;
|
||||
}
|
||||
|
||||
// Receive Queue
|
||||
get rQlen() {
|
||||
return this._rQlen - this._rQi;
|
||||
}
|
||||
|
||||
rQpeek8() {
|
||||
return this._rQ[this._rQi];
|
||||
}
|
||||
|
||||
rQskipBytes(bytes) {
|
||||
this._rQi += bytes;
|
||||
}
|
||||
|
||||
rQshift8() {
|
||||
return this._rQshift(1);
|
||||
}
|
||||
|
||||
rQshift16() {
|
||||
return this._rQshift(2);
|
||||
}
|
||||
|
||||
rQshift32() {
|
||||
return this._rQshift(4);
|
||||
}
|
||||
|
||||
// TODO(directxman12): test performance with these vs a DataView
|
||||
_rQshift(bytes) {
|
||||
let res = 0;
|
||||
for (let byte = bytes - 1; byte >= 0; byte--) {
|
||||
res += this._rQ[this._rQi++] << (byte * 8);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
rQshiftStr(len) {
|
||||
if (typeof(len) === 'undefined') { len = this.rQlen; }
|
||||
let str = "";
|
||||
// Handle large arrays in steps to avoid long strings on the stack
|
||||
for (let i = 0; i < len; i += 4096) {
|
||||
let part = this.rQshiftBytes(Math.min(4096, len - i));
|
||||
str += String.fromCharCode.apply(null, part);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
rQshiftBytes(len) {
|
||||
if (typeof(len) === 'undefined') { len = this.rQlen; }
|
||||
this._rQi += len;
|
||||
return new Uint8Array(this._rQ.buffer, this._rQi - len, len);
|
||||
}
|
||||
|
||||
rQshiftTo(target, len) {
|
||||
if (len === undefined) { len = this.rQlen; }
|
||||
// TODO: make this just use set with views when using a ArrayBuffer to store the rQ
|
||||
target.set(new Uint8Array(this._rQ.buffer, this._rQi, len));
|
||||
this._rQi += len;
|
||||
}
|
||||
|
||||
rQslice(start, end = this.rQlen) {
|
||||
return new Uint8Array(this._rQ.buffer, this._rQi + start, end - start);
|
||||
}
|
||||
|
||||
// Check to see if we must wait for 'num' bytes (default to FBU.bytes)
|
||||
// to be available in the receive queue. Return true if we need to
|
||||
// wait (and possibly print a debug message), otherwise false.
|
||||
rQwait(msg, num, goback) {
|
||||
if (this.rQlen < num) {
|
||||
if (goback) {
|
||||
if (this._rQi < goback) {
|
||||
throw new Error("rQwait cannot backup " + goback + " bytes");
|
||||
}
|
||||
this._rQi -= goback;
|
||||
}
|
||||
return true; // true means need more data
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send Queue
|
||||
|
||||
flush() {
|
||||
if (this._sQlen > 0 && this._websocket.readyState === WebSocket.OPEN) {
|
||||
this._websocket.send(this._encode_message());
|
||||
this._sQlen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
send(arr) {
|
||||
this._sQ.set(arr, this._sQlen);
|
||||
this._sQlen += arr.length;
|
||||
this.flush();
|
||||
}
|
||||
|
||||
send_string(str) {
|
||||
this.send(str.split('').map(chr => chr.charCodeAt(0)));
|
||||
}
|
||||
|
||||
// Event Handlers
|
||||
off(evt) {
|
||||
this._eventHandlers[evt] = () => {};
|
||||
}
|
||||
|
||||
on(evt, handler) {
|
||||
this._eventHandlers[evt] = handler;
|
||||
}
|
||||
|
||||
_allocate_buffers() {
|
||||
this._rQ = new Uint8Array(this._rQbufferSize);
|
||||
this._sQ = new Uint8Array(this._sQbufferSize);
|
||||
}
|
||||
|
||||
init() {
|
||||
this._allocate_buffers();
|
||||
this._rQi = 0;
|
||||
this._websocket = null;
|
||||
}
|
||||
|
||||
open(uri, protocols) {
|
||||
this.init();
|
||||
|
||||
this._websocket = new WebSocket(uri, protocols);
|
||||
this._websocket.binaryType = 'arraybuffer';
|
||||
|
||||
this._websocket.onmessage = this._recv_message.bind(this);
|
||||
this._websocket.onopen = () => {
|
||||
Log.Debug('>> WebSock.onopen');
|
||||
if (this._websocket.protocol) {
|
||||
Log.Info("Server choose sub-protocol: " + this._websocket.protocol);
|
||||
}
|
||||
|
||||
this._eventHandlers.open();
|
||||
Log.Debug("<< WebSock.onopen");
|
||||
};
|
||||
this._websocket.onclose = (e) => {
|
||||
Log.Debug(">> WebSock.onclose");
|
||||
this._eventHandlers.close(e);
|
||||
Log.Debug("<< WebSock.onclose");
|
||||
};
|
||||
this._websocket.onerror = (e) => {
|
||||
Log.Debug(">> WebSock.onerror: " + e);
|
||||
this._eventHandlers.error(e);
|
||||
Log.Debug("<< WebSock.onerror: " + e);
|
||||
};
|
||||
}
|
||||
|
||||
close() {
|
||||
if (this._websocket) {
|
||||
if ((this._websocket.readyState === WebSocket.OPEN) ||
|
||||
(this._websocket.readyState === WebSocket.CONNECTING)) {
|
||||
Log.Info("Closing WebSocket connection");
|
||||
this._websocket.close();
|
||||
}
|
||||
|
||||
this._websocket.onmessage = () => {};
|
||||
}
|
||||
}
|
||||
|
||||
// private methods
|
||||
_encode_message() {
|
||||
// Put in a binary arraybuffer
|
||||
// according to the spec, you can send ArrayBufferViews with the send method
|
||||
return new Uint8Array(this._sQ.buffer, 0, this._sQlen);
|
||||
}
|
||||
|
||||
_expand_compact_rQ(min_fit) {
|
||||
const resizeNeeded = min_fit || this.rQlen > this._rQbufferSize / 2;
|
||||
if (resizeNeeded) {
|
||||
if (!min_fit) {
|
||||
// just double the size if we need to do compaction
|
||||
this._rQbufferSize *= 2;
|
||||
} else {
|
||||
// otherwise, make sure we satisy rQlen - rQi + min_fit < rQbufferSize / 8
|
||||
this._rQbufferSize = (this.rQlen + min_fit) * 8;
|
||||
}
|
||||
}
|
||||
|
||||
// we don't want to grow unboundedly
|
||||
if (this._rQbufferSize > MAX_RQ_GROW_SIZE) {
|
||||
this._rQbufferSize = MAX_RQ_GROW_SIZE;
|
||||
if (this._rQbufferSize - this.rQlen < min_fit) {
|
||||
throw new Error("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit");
|
||||
}
|
||||
}
|
||||
|
||||
if (resizeNeeded) {
|
||||
const old_rQbuffer = this._rQ.buffer;
|
||||
this._rQmax = this._rQbufferSize / 8;
|
||||
this._rQ = new Uint8Array(this._rQbufferSize);
|
||||
this._rQ.set(new Uint8Array(old_rQbuffer, this._rQi));
|
||||
} else {
|
||||
if (ENABLE_COPYWITHIN) {
|
||||
this._rQ.copyWithin(0, this._rQi);
|
||||
} else {
|
||||
this._rQ.set(new Uint8Array(this._rQ.buffer, this._rQi));
|
||||
}
|
||||
}
|
||||
|
||||
this._rQlen = this._rQlen - this._rQi;
|
||||
this._rQi = 0;
|
||||
}
|
||||
|
||||
_decode_message(data) {
|
||||
// push arraybuffer values onto the end
|
||||
const u8 = new Uint8Array(data);
|
||||
if (u8.length > this._rQbufferSize - this._rQlen) {
|
||||
this._expand_compact_rQ(u8.length);
|
||||
}
|
||||
this._rQ.set(u8, this._rQlen);
|
||||
this._rQlen += u8.length;
|
||||
}
|
||||
|
||||
_recv_message(e) {
|
||||
this._decode_message(e.data);
|
||||
if (this.rQlen > 0) {
|
||||
this._eventHandlers.message();
|
||||
// Compact the receive queue
|
||||
if (this._rQlen == this._rQi) {
|
||||
this._rQlen = 0;
|
||||
this._rQi = 0;
|
||||
} else if (this._rQlen > this._rQmax) {
|
||||
this._expand_compact_rQ();
|
||||
}
|
||||
} else {
|
||||
Log.Debug("Ignoring empty message");
|
||||
}
|
||||
}
|
||||
}
|
15
public/novnc/vendor/browser-es-module-loader/README.md
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
Custom Browser ES Module Loader
|
||||
===============================
|
||||
|
||||
This is a module loader using babel and the ES Module Loader polyfill.
|
||||
It's based heavily on
|
||||
https://github.com/ModuleLoader/browser-es-module-loader, but uses
|
||||
WebWorkers to compile the modules in the background.
|
||||
|
||||
To generate, run `rollup -c` in this directory, and then run `browserify
|
||||
src/babel-worker.js > dist/babel-worker.js`.
|
||||
|
||||
LICENSE
|
||||
-------
|
||||
|
||||
MIT
|
55799
public/novnc/vendor/browser-es-module-loader/dist/babel-worker.js
vendored
Normal file
1486
public/novnc/vendor/browser-es-module-loader/dist/browser-es-module-loader.js
vendored
Normal file
1
public/novnc/vendor/browser-es-module-loader/dist/browser-es-module-loader.js.map
vendored
Normal file
16
public/novnc/vendor/browser-es-module-loader/rollup.config.js
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
import nodeResolve from 'rollup-plugin-node-resolve';
|
||||
|
||||
export default {
|
||||
entry: 'src/browser-es-module-loader.js',
|
||||
dest: 'dist/browser-es-module-loader.js',
|
||||
format: 'umd',
|
||||
moduleName: 'BrowserESModuleLoader',
|
||||
sourceMap: true,
|
||||
|
||||
plugins: [
|
||||
nodeResolve(),
|
||||
],
|
||||
|
||||
// skip rollup warnings (specifically the eval warning)
|
||||
onwarn: function() {}
|
||||
};
|
25
public/novnc/vendor/browser-es-module-loader/src/babel-worker.js
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
/*import { transform as babelTransform } from 'babel-core';
|
||||
import babelTransformDynamicImport from 'babel-plugin-syntax-dynamic-import';
|
||||
import babelTransformES2015ModulesSystemJS from 'babel-plugin-transform-es2015-modules-systemjs';*/
|
||||
|
||||
// sadly, due to how rollup works, we can't use es6 imports here
|
||||
var babelTransform = require('babel-core').transform;
|
||||
var babelTransformDynamicImport = require('babel-plugin-syntax-dynamic-import');
|
||||
var babelTransformES2015ModulesSystemJS = require('babel-plugin-transform-es2015-modules-systemjs');
|
||||
var babelPresetES2015 = require('babel-preset-es2015');
|
||||
|
||||
self.onmessage = function (evt) {
|
||||
// transform source with Babel
|
||||
var output = babelTransform(evt.data.source, {
|
||||
compact: false,
|
||||
filename: evt.data.key + '!transpiled',
|
||||
sourceFileName: evt.data.key,
|
||||
moduleIds: false,
|
||||
sourceMaps: 'inline',
|
||||
babelrc: false,
|
||||
plugins: [babelTransformDynamicImport, babelTransformES2015ModulesSystemJS],
|
||||
presets: [babelPresetES2015],
|
||||
});
|
||||
|
||||
self.postMessage({key: evt.data.key, code: output.code, source: evt.data.source});
|
||||
};
|
280
public/novnc/vendor/browser-es-module-loader/src/browser-es-module-loader.js
vendored
Normal file
@ -0,0 +1,280 @@
|
||||
import RegisterLoader from 'es-module-loader/core/register-loader.js';
|
||||
import { InternalModuleNamespace as ModuleNamespace } from 'es-module-loader/core/loader-polyfill.js';
|
||||
|
||||
import { baseURI, global, isBrowser } from 'es-module-loader/core/common.js';
|
||||
import { resolveIfNotPlain } from 'es-module-loader/core/resolve.js';
|
||||
|
||||
var loader;
|
||||
|
||||
// <script type="module"> support
|
||||
var anonSources = {};
|
||||
if (typeof document != 'undefined' && document.getElementsByTagName) {
|
||||
var handleError = function(err) {
|
||||
// dispatch an error event so that we can display in errors in browsers
|
||||
// that don't yet support unhandledrejection
|
||||
if (window.onunhandledrejection === undefined) {
|
||||
try {
|
||||
var evt = new Event('error');
|
||||
} catch (_eventError) {
|
||||
var evt = document.createEvent('Event');
|
||||
evt.initEvent('error', true, true);
|
||||
}
|
||||
evt.message = err.message;
|
||||
if (err.fileName) {
|
||||
evt.filename = err.fileName;
|
||||
evt.lineno = err.lineNumber;
|
||||
evt.colno = err.columnNumber;
|
||||
} else if (err.sourceURL) {
|
||||
evt.filename = err.sourceURL;
|
||||
evt.lineno = err.line;
|
||||
evt.colno = err.column;
|
||||
}
|
||||
evt.error = err;
|
||||
window.dispatchEvent(evt);
|
||||
}
|
||||
|
||||
// throw so it still shows up in the console
|
||||
throw err;
|
||||
}
|
||||
|
||||
var ready = function() {
|
||||
document.removeEventListener('DOMContentLoaded', ready, false );
|
||||
|
||||
var anonCnt = 0;
|
||||
|
||||
var scripts = document.getElementsByTagName('script');
|
||||
for (var i = 0; i < scripts.length; i++) {
|
||||
var script = scripts[i];
|
||||
if (script.type == 'module' && !script.loaded) {
|
||||
script.loaded = true;
|
||||
if (script.src) {
|
||||
loader.import(script.src).catch(handleError);
|
||||
}
|
||||
// anonymous modules supported via a custom naming scheme and registry
|
||||
else {
|
||||
var uri = './<anon' + ++anonCnt + '>.js';
|
||||
if (script.id !== ""){
|
||||
uri = "./" + script.id;
|
||||
}
|
||||
|
||||
var anonName = resolveIfNotPlain(uri, baseURI);
|
||||
anonSources[anonName] = script.innerHTML;
|
||||
loader.import(anonName).catch(handleError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// simple DOM ready
|
||||
if (document.readyState !== 'loading')
|
||||
setTimeout(ready);
|
||||
else
|
||||
document.addEventListener('DOMContentLoaded', ready, false);
|
||||
}
|
||||
|
||||
function BrowserESModuleLoader(baseKey) {
|
||||
if (baseKey)
|
||||
this.baseKey = resolveIfNotPlain(baseKey, baseURI) || resolveIfNotPlain('./' + baseKey, baseURI);
|
||||
|
||||
RegisterLoader.call(this);
|
||||
|
||||
var loader = this;
|
||||
|
||||
// ensure System.register is available
|
||||
global.System = global.System || {};
|
||||
if (typeof global.System.register == 'function')
|
||||
var prevRegister = global.System.register;
|
||||
global.System.register = function() {
|
||||
loader.register.apply(loader, arguments);
|
||||
if (prevRegister)
|
||||
prevRegister.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
BrowserESModuleLoader.prototype = Object.create(RegisterLoader.prototype);
|
||||
|
||||
// normalize is never given a relative name like "./x", that part is already handled
|
||||
BrowserESModuleLoader.prototype[RegisterLoader.resolve] = function(key, parent) {
|
||||
var resolved = RegisterLoader.prototype[RegisterLoader.resolve].call(this, key, parent || this.baseKey) || key;
|
||||
if (!resolved)
|
||||
throw new RangeError('ES module loader does not resolve plain module names, resolving "' + key + '" to ' + parent);
|
||||
|
||||
return resolved;
|
||||
};
|
||||
|
||||
function xhrFetch(url, resolve, reject) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
var load = function(source) {
|
||||
resolve(xhr.responseText);
|
||||
}
|
||||
var error = function() {
|
||||
reject(new Error('XHR error' + (xhr.status ? ' (' + xhr.status + (xhr.statusText ? ' ' + xhr.statusText : '') + ')' : '') + ' loading ' + url));
|
||||
}
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === 4) {
|
||||
// in Chrome on file:/// URLs, status is 0
|
||||
if (xhr.status == 0) {
|
||||
if (xhr.responseText) {
|
||||
load();
|
||||
}
|
||||
else {
|
||||
// when responseText is empty, wait for load or error event
|
||||
// to inform if it is a 404 or empty file
|
||||
xhr.addEventListener('error', error);
|
||||
xhr.addEventListener('load', load);
|
||||
}
|
||||
}
|
||||
else if (xhr.status === 200) {
|
||||
load();
|
||||
}
|
||||
else {
|
||||
error();
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.open("GET", url, true);
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
var WorkerPool = function (script, size) {
|
||||
var current = document.currentScript;
|
||||
// IE doesn't support currentScript
|
||||
if (!current) {
|
||||
// Find an entry with out basename
|
||||
var scripts = document.getElementsByTagName('script');
|
||||
for (var i = 0; i < scripts.length; i++) {
|
||||
if (scripts[i].src.indexOf("browser-es-module-loader.js") !== -1) {
|
||||
current = scripts[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!current)
|
||||
throw Error("Could not find own <script> element");
|
||||
}
|
||||
script = current.src.substr(0, current.src.lastIndexOf("/")) + "/" + script;
|
||||
this._workers = new Array(size);
|
||||
this._ind = 0;
|
||||
this._size = size;
|
||||
this._jobs = 0;
|
||||
this.onmessage = undefined;
|
||||
this._stopTimeout = undefined;
|
||||
for (var i = 0; i < size; i++) {
|
||||
var wrkr = new Worker(script);
|
||||
wrkr._count = 0;
|
||||
wrkr._ind = i;
|
||||
wrkr.onmessage = this._onmessage.bind(this, wrkr);
|
||||
wrkr.onerror = this._onerror.bind(this);
|
||||
this._workers[i] = wrkr;
|
||||
}
|
||||
|
||||
this._checkJobs();
|
||||
};
|
||||
WorkerPool.prototype = {
|
||||
postMessage: function (msg) {
|
||||
if (this._stopTimeout !== undefined) {
|
||||
clearTimeout(this._stopTimeout);
|
||||
this._stopTimeout = undefined;
|
||||
}
|
||||
var wrkr = this._workers[this._ind % this._size];
|
||||
wrkr._count++;
|
||||
this._jobs++;
|
||||
wrkr.postMessage(msg);
|
||||
this._ind++;
|
||||
},
|
||||
|
||||
_onmessage: function (wrkr, evt) {
|
||||
wrkr._count--;
|
||||
this._jobs--;
|
||||
this.onmessage(evt, wrkr);
|
||||
this._checkJobs();
|
||||
},
|
||||
|
||||
_onerror: function(err) {
|
||||
try {
|
||||
var evt = new Event('error');
|
||||
} catch (_eventError) {
|
||||
var evt = document.createEvent('Event');
|
||||
evt.initEvent('error', true, true);
|
||||
}
|
||||
evt.message = err.message;
|
||||
evt.filename = err.filename;
|
||||
evt.lineno = err.lineno;
|
||||
evt.colno = err.colno;
|
||||
evt.error = err.error;
|
||||
window.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
_checkJobs: function () {
|
||||
if (this._jobs === 0 && this._stopTimeout === undefined) {
|
||||
// wait for 2s of inactivity before stopping (that should be enough for local loading)
|
||||
this._stopTimeout = setTimeout(this._stop.bind(this), 2000);
|
||||
}
|
||||
},
|
||||
|
||||
_stop: function () {
|
||||
this._workers.forEach(function(wrkr) {
|
||||
wrkr.terminate();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var promiseMap = new Map();
|
||||
var babelWorker = new WorkerPool('babel-worker.js', 3);
|
||||
babelWorker.onmessage = function (evt) {
|
||||
var promFuncs = promiseMap.get(evt.data.key);
|
||||
promFuncs.resolve(evt.data);
|
||||
promiseMap.delete(evt.data.key);
|
||||
};
|
||||
|
||||
// instantiate just needs to run System.register
|
||||
// so we fetch the source, convert into the Babel System module format, then evaluate it
|
||||
BrowserESModuleLoader.prototype[RegisterLoader.instantiate] = function(key, processAnonRegister) {
|
||||
var loader = this;
|
||||
|
||||
// load as ES with Babel converting into System.register
|
||||
return new Promise(function(resolve, reject) {
|
||||
// anonymous module
|
||||
if (anonSources[key]) {
|
||||
resolve(anonSources[key])
|
||||
anonSources[key] = undefined;
|
||||
}
|
||||
// otherwise we fetch
|
||||
else {
|
||||
xhrFetch(key, resolve, reject);
|
||||
}
|
||||
})
|
||||
.then(function(source) {
|
||||
// check our cache first
|
||||
var cacheEntry = localStorage.getItem(key);
|
||||
if (cacheEntry) {
|
||||
cacheEntry = JSON.parse(cacheEntry);
|
||||
// TODO: store a hash instead
|
||||
if (cacheEntry.source === source) {
|
||||
return Promise.resolve({key: key, code: cacheEntry.code, source: cacheEntry.source});
|
||||
}
|
||||
}
|
||||
return new Promise(function (resolve, reject) {
|
||||
promiseMap.set(key, {resolve: resolve, reject: reject});
|
||||
babelWorker.postMessage({key: key, source: source});
|
||||
});
|
||||
}).then(function (data) {
|
||||
// evaluate without require, exports and module variables
|
||||
// we leave module in for now to allow module.require access
|
||||
try {
|
||||
var cacheEntry = JSON.stringify({source: data.source, code: data.code});
|
||||
localStorage.setItem(key, cacheEntry);
|
||||
} catch (e) {
|
||||
if (window.console) {
|
||||
window.console.warn('Unable to cache transpiled version of ' + key + ': ' + e);
|
||||
}
|
||||
}
|
||||
(0, eval)(data.code + '\n//# sourceURL=' + data.key + '!transpiled');
|
||||
processAnonRegister();
|
||||
});
|
||||
};
|
||||
|
||||
// create a default loader instance in the browser
|
||||
if (isBrowser)
|
||||
loader = new BrowserESModuleLoader();
|
||||
|
||||
export default BrowserESModuleLoader;
|
21
public/novnc/vendor/pako/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (C) 2014-2016 by Vitaly Puzrin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
6
public/novnc/vendor/pako/README.md
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
This is an ES6-modules-compatible version of
|
||||
https://github.com/nodeca/pako, based on pako version 1.0.3.
|
||||
|
||||
It's more-or-less a direct translation of the original, with unused parts
|
||||
removed, and the dynamic support for non-typed arrays removed (since ES6
|
||||
modules don't work well with dynamic exports).
|
45
public/novnc/vendor/pako/lib/utils/common.js
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
// reduce buffer size, avoiding mem copy
|
||||
export function shrinkBuf (buf, size) {
|
||||
if (buf.length === size) { return buf; }
|
||||
if (buf.subarray) { return buf.subarray(0, size); }
|
||||
buf.length = size;
|
||||
return buf;
|
||||
};
|
||||
|
||||
|
||||
export function arraySet (dest, src, src_offs, len, dest_offs) {
|
||||
if (src.subarray && dest.subarray) {
|
||||
dest.set(src.subarray(src_offs, src_offs + len), dest_offs);
|
||||
return;
|
||||
}
|
||||
// Fallback to ordinary array
|
||||
for (var i = 0; i < len; i++) {
|
||||
dest[dest_offs + i] = src[src_offs + i];
|
||||
}
|
||||
}
|
||||
|
||||
// Join array of chunks to single array.
|
||||
export function flattenChunks (chunks) {
|
||||
var i, l, len, pos, chunk, result;
|
||||
|
||||
// calculate data length
|
||||
len = 0;
|
||||
for (i = 0, l = chunks.length; i < l; i++) {
|
||||
len += chunks[i].length;
|
||||
}
|
||||
|
||||
// join chunks
|
||||
result = new Uint8Array(len);
|
||||
pos = 0;
|
||||
for (i = 0, l = chunks.length; i < l; i++) {
|
||||
chunk = chunks[i];
|
||||
result.set(chunk, pos);
|
||||
pos += chunk.length;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export var Buf8 = Uint8Array;
|
||||
export var Buf16 = Uint16Array;
|
||||
export var Buf32 = Int32Array;
|
27
public/novnc/vendor/pako/lib/zlib/adler32.js
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// Note: adler32 takes 12% for level 0 and 2% for level 6.
|
||||
// It doesn't worth to make additional optimizationa as in original.
|
||||
// Small size is preferable.
|
||||
|
||||
export default function adler32(adler, buf, len, pos) {
|
||||
var s1 = (adler & 0xffff) |0,
|
||||
s2 = ((adler >>> 16) & 0xffff) |0,
|
||||
n = 0;
|
||||
|
||||
while (len !== 0) {
|
||||
// Set limit ~ twice less than 5552, to keep
|
||||
// s2 in 31-bits, because we force signed ints.
|
||||
// in other case %= will fail.
|
||||
n = len > 2000 ? 2000 : len;
|
||||
len -= n;
|
||||
|
||||
do {
|
||||
s1 = (s1 + buf[pos++]) |0;
|
||||
s2 = (s2 + s1) |0;
|
||||
} while (--n);
|
||||
|
||||
s1 %= 65521;
|
||||
s2 %= 65521;
|
||||
}
|
||||
|
||||
return (s1 | (s2 << 16)) |0;
|
||||
}
|
47
public/novnc/vendor/pako/lib/zlib/constants.js
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
export default {
|
||||
|
||||
/* Allowed flush values; see deflate() and inflate() below for details */
|
||||
Z_NO_FLUSH: 0,
|
||||
Z_PARTIAL_FLUSH: 1,
|
||||
Z_SYNC_FLUSH: 2,
|
||||
Z_FULL_FLUSH: 3,
|
||||
Z_FINISH: 4,
|
||||
Z_BLOCK: 5,
|
||||
Z_TREES: 6,
|
||||
|
||||
/* Return codes for the compression/decompression functions. Negative values
|
||||
* are errors, positive values are used for special but normal events.
|
||||
*/
|
||||
Z_OK: 0,
|
||||
Z_STREAM_END: 1,
|
||||
Z_NEED_DICT: 2,
|
||||
Z_ERRNO: -1,
|
||||
Z_STREAM_ERROR: -2,
|
||||
Z_DATA_ERROR: -3,
|
||||
//Z_MEM_ERROR: -4,
|
||||
Z_BUF_ERROR: -5,
|
||||
//Z_VERSION_ERROR: -6,
|
||||
|
||||
/* compression levels */
|
||||
Z_NO_COMPRESSION: 0,
|
||||
Z_BEST_SPEED: 1,
|
||||
Z_BEST_COMPRESSION: 9,
|
||||
Z_DEFAULT_COMPRESSION: -1,
|
||||
|
||||
|
||||
Z_FILTERED: 1,
|
||||
Z_HUFFMAN_ONLY: 2,
|
||||
Z_RLE: 3,
|
||||
Z_FIXED: 4,
|
||||
Z_DEFAULT_STRATEGY: 0,
|
||||
|
||||
/* Possible values of the data_type field (though see inflate()) */
|
||||
Z_BINARY: 0,
|
||||
Z_TEXT: 1,
|
||||
//Z_ASCII: 1, // = Z_TEXT (deprecated)
|
||||
Z_UNKNOWN: 2,
|
||||
|
||||
/* The deflate compression method */
|
||||
Z_DEFLATED: 8
|
||||
//Z_NULL: null // Use -1 or null inline, depending on var type
|
||||
};
|
36
public/novnc/vendor/pako/lib/zlib/crc32.js
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
// Note: we can't get significant speed boost here.
|
||||
// So write code to minimize size - no pregenerated tables
|
||||
// and array tools dependencies.
|
||||
|
||||
|
||||
// Use ordinary array, since untyped makes no boost here
|
||||
export default function makeTable() {
|
||||
var c, table = [];
|
||||
|
||||
for (var n = 0; n < 256; n++) {
|
||||
c = n;
|
||||
for (var k = 0; k < 8; k++) {
|
||||
c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
|
||||
}
|
||||
table[n] = c;
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
// Create table on load. Just 255 signed longs. Not a problem.
|
||||
var crcTable = makeTable();
|
||||
|
||||
|
||||
function crc32(crc, buf, len, pos) {
|
||||
var t = crcTable,
|
||||
end = pos + len;
|
||||
|
||||
crc ^= -1;
|
||||
|
||||
for (var i = pos; i < end; i++) {
|
||||
crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF];
|
||||
}
|
||||
|
||||
return (crc ^ (-1)); // >>> 0;
|
||||
}
|
1846
public/novnc/vendor/pako/lib/zlib/deflate.js
vendored
Normal file
35
public/novnc/vendor/pako/lib/zlib/gzheader.js
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
export default function GZheader() {
|
||||
/* true if compressed data believed to be text */
|
||||
this.text = 0;
|
||||
/* modification time */
|
||||
this.time = 0;
|
||||
/* extra flags (not used when writing a gzip file) */
|
||||
this.xflags = 0;
|
||||
/* operating system */
|
||||
this.os = 0;
|
||||
/* pointer to extra field or Z_NULL if none */
|
||||
this.extra = null;
|
||||
/* extra field length (valid if extra != Z_NULL) */
|
||||
this.extra_len = 0; // Actually, we don't need it in JS,
|
||||
// but leave for few code modifications
|
||||
|
||||
//
|
||||
// Setup limits is not necessary because in js we should not preallocate memory
|
||||
// for inflate use constant limit in 65536 bytes
|
||||
//
|
||||
|
||||
/* space at extra (only when reading header) */
|
||||
// this.extra_max = 0;
|
||||
/* pointer to zero-terminated file name or Z_NULL */
|
||||
this.name = '';
|
||||
/* space at name (only when reading header) */
|
||||
// this.name_max = 0;
|
||||
/* pointer to zero-terminated comment or Z_NULL */
|
||||
this.comment = '';
|
||||
/* space at comment (only when reading header) */
|
||||
// this.comm_max = 0;
|
||||
/* true if there was or will be a header crc */
|
||||
this.hcrc = 0;
|
||||
/* true when done reading gzip header (not used when writing a gzip file) */
|
||||
this.done = false;
|
||||
}
|
324
public/novnc/vendor/pako/lib/zlib/inffast.js
vendored
Normal file
@ -0,0 +1,324 @@
|
||||
// See state defs from inflate.js
|
||||
var BAD = 30; /* got a data error -- remain here until reset */
|
||||
var TYPE = 12; /* i: waiting for type bits, including last-flag bit */
|
||||
|
||||
/*
|
||||
Decode literal, length, and distance codes and write out the resulting
|
||||
literal and match bytes until either not enough input or output is
|
||||
available, an end-of-block is encountered, or a data error is encountered.
|
||||
When large enough input and output buffers are supplied to inflate(), for
|
||||
example, a 16K input buffer and a 64K output buffer, more than 95% of the
|
||||
inflate execution time is spent in this routine.
|
||||
|
||||
Entry assumptions:
|
||||
|
||||
state.mode === LEN
|
||||
strm.avail_in >= 6
|
||||
strm.avail_out >= 258
|
||||
start >= strm.avail_out
|
||||
state.bits < 8
|
||||
|
||||
On return, state.mode is one of:
|
||||
|
||||
LEN -- ran out of enough output space or enough available input
|
||||
TYPE -- reached end of block code, inflate() to interpret next block
|
||||
BAD -- error in block data
|
||||
|
||||
Notes:
|
||||
|
||||
- The maximum input bits used by a length/distance pair is 15 bits for the
|
||||
length code, 5 bits for the length extra, 15 bits for the distance code,
|
||||
and 13 bits for the distance extra. This totals 48 bits, or six bytes.
|
||||
Therefore if strm.avail_in >= 6, then there is enough input to avoid
|
||||
checking for available input while decoding.
|
||||
|
||||
- The maximum bytes that a single length/distance pair can output is 258
|
||||
bytes, which is the maximum length that can be coded. inflate_fast()
|
||||
requires strm.avail_out >= 258 for each loop to avoid checking for
|
||||
output space.
|
||||
*/
|
||||
export default function inflate_fast(strm, start) {
|
||||
var state;
|
||||
var _in; /* local strm.input */
|
||||
var last; /* have enough input while in < last */
|
||||
var _out; /* local strm.output */
|
||||
var beg; /* inflate()'s initial strm.output */
|
||||
var end; /* while out < end, enough space available */
|
||||
//#ifdef INFLATE_STRICT
|
||||
var dmax; /* maximum distance from zlib header */
|
||||
//#endif
|
||||
var wsize; /* window size or zero if not using window */
|
||||
var whave; /* valid bytes in the window */
|
||||
var wnext; /* window write index */
|
||||
// Use `s_window` instead `window`, avoid conflict with instrumentation tools
|
||||
var s_window; /* allocated sliding window, if wsize != 0 */
|
||||
var hold; /* local strm.hold */
|
||||
var bits; /* local strm.bits */
|
||||
var lcode; /* local strm.lencode */
|
||||
var dcode; /* local strm.distcode */
|
||||
var lmask; /* mask for first level of length codes */
|
||||
var dmask; /* mask for first level of distance codes */
|
||||
var here; /* retrieved table entry */
|
||||
var op; /* code bits, operation, extra bits, or */
|
||||
/* window position, window bytes to copy */
|
||||
var len; /* match length, unused bytes */
|
||||
var dist; /* match distance */
|
||||
var from; /* where to copy match from */
|
||||
var from_source;
|
||||
|
||||
|
||||
var input, output; // JS specific, because we have no pointers
|
||||
|
||||
/* copy state to local variables */
|
||||
state = strm.state;
|
||||
//here = state.here;
|
||||
_in = strm.next_in;
|
||||
input = strm.input;
|
||||
last = _in + (strm.avail_in - 5);
|
||||
_out = strm.next_out;
|
||||
output = strm.output;
|
||||
beg = _out - (start - strm.avail_out);
|
||||
end = _out + (strm.avail_out - 257);
|
||||
//#ifdef INFLATE_STRICT
|
||||
dmax = state.dmax;
|
||||
//#endif
|
||||
wsize = state.wsize;
|
||||
whave = state.whave;
|
||||
wnext = state.wnext;
|
||||
s_window = state.window;
|
||||
hold = state.hold;
|
||||
bits = state.bits;
|
||||
lcode = state.lencode;
|
||||
dcode = state.distcode;
|
||||
lmask = (1 << state.lenbits) - 1;
|
||||
dmask = (1 << state.distbits) - 1;
|
||||
|
||||
|
||||
/* decode literals and length/distances until end-of-block or not enough
|
||||
input data or output space */
|
||||
|
||||
top:
|
||||
do {
|
||||
if (bits < 15) {
|
||||
hold += input[_in++] << bits;
|
||||
bits += 8;
|
||||
hold += input[_in++] << bits;
|
||||
bits += 8;
|
||||
}
|
||||
|
||||
here = lcode[hold & lmask];
|
||||
|
||||
dolen:
|
||||
for (;;) { // Goto emulation
|
||||
op = here >>> 24/*here.bits*/;
|
||||
hold >>>= op;
|
||||
bits -= op;
|
||||
op = (here >>> 16) & 0xff/*here.op*/;
|
||||
if (op === 0) { /* literal */
|
||||
//Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
|
||||
// "inflate: literal '%c'\n" :
|
||||
// "inflate: literal 0x%02x\n", here.val));
|
||||
output[_out++] = here & 0xffff/*here.val*/;
|
||||
}
|
||||
else if (op & 16) { /* length base */
|
||||
len = here & 0xffff/*here.val*/;
|
||||
op &= 15; /* number of extra bits */
|
||||
if (op) {
|
||||
if (bits < op) {
|
||||
hold += input[_in++] << bits;
|
||||
bits += 8;
|
||||
}
|
||||
len += hold & ((1 << op) - 1);
|
||||
hold >>>= op;
|
||||
bits -= op;
|
||||
}
|
||||
//Tracevv((stderr, "inflate: length %u\n", len));
|
||||
if (bits < 15) {
|
||||
hold += input[_in++] << bits;
|
||||
bits += 8;
|
||||
hold += input[_in++] << bits;
|
||||
bits += 8;
|
||||
}
|
||||
here = dcode[hold & dmask];
|
||||
|
||||
dodist:
|
||||
for (;;) { // goto emulation
|
||||
op = here >>> 24/*here.bits*/;
|
||||
hold >>>= op;
|
||||
bits -= op;
|
||||
op = (here >>> 16) & 0xff/*here.op*/;
|
||||
|
||||
if (op & 16) { /* distance base */
|
||||
dist = here & 0xffff/*here.val*/;
|
||||
op &= 15; /* number of extra bits */
|
||||
if (bits < op) {
|
||||
hold += input[_in++] << bits;
|
||||
bits += 8;
|
||||
if (bits < op) {
|
||||
hold += input[_in++] << bits;
|
||||
bits += 8;
|
||||
}
|
||||
}
|
||||
dist += hold & ((1 << op) - 1);
|
||||
//#ifdef INFLATE_STRICT
|
||||
if (dist > dmax) {
|
||||
strm.msg = 'invalid distance too far back';
|
||||
state.mode = BAD;
|
||||
break top;
|
||||
}
|
||||
//#endif
|
||||
hold >>>= op;
|
||||
bits -= op;
|
||||
//Tracevv((stderr, "inflate: distance %u\n", dist));
|
||||
op = _out - beg; /* max distance in output */
|
||||
if (dist > op) { /* see if copy from window */
|
||||
op = dist - op; /* distance back in window */
|
||||
if (op > whave) {
|
||||
if (state.sane) {
|
||||
strm.msg = 'invalid distance too far back';
|
||||
state.mode = BAD;
|
||||
break top;
|
||||
}
|
||||
|
||||
// (!) This block is disabled in zlib defailts,
|
||||
// don't enable it for binary compatibility
|
||||
//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
|
||||
// if (len <= op - whave) {
|
||||
// do {
|
||||
// output[_out++] = 0;
|
||||
// } while (--len);
|
||||
// continue top;
|
||||
// }
|
||||
// len -= op - whave;
|
||||
// do {
|
||||
// output[_out++] = 0;
|
||||
// } while (--op > whave);
|
||||
// if (op === 0) {
|
||||
// from = _out - dist;
|
||||
// do {
|
||||
// output[_out++] = output[from++];
|
||||
// } while (--len);
|
||||
// continue top;
|
||||
// }
|
||||
//#endif
|
||||
}
|
||||
from = 0; // window index
|
||||
from_source = s_window;
|
||||
if (wnext === 0) { /* very common case */
|
||||
from += wsize - op;
|
||||
if (op < len) { /* some from window */
|
||||
len -= op;
|
||||
do {
|
||||
output[_out++] = s_window[from++];
|
||||
} while (--op);
|
||||
from = _out - dist; /* rest from output */
|
||||
from_source = output;
|
||||
}
|
||||
}
|
||||
else if (wnext < op) { /* wrap around window */
|
||||
from += wsize + wnext - op;
|
||||
op -= wnext;
|
||||
if (op < len) { /* some from end of window */
|
||||
len -= op;
|
||||
do {
|
||||
output[_out++] = s_window[from++];
|
||||
} while (--op);
|
||||
from = 0;
|
||||
if (wnext < len) { /* some from start of window */
|
||||
op = wnext;
|
||||
len -= op;
|
||||
do {
|
||||
output[_out++] = s_window[from++];
|
||||
} while (--op);
|
||||
from = _out - dist; /* rest from output */
|
||||
from_source = output;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* contiguous in window */
|
||||
from += wnext - op;
|
||||
if (op < len) { /* some from window */
|
||||
len -= op;
|
||||
do {
|
||||
output[_out++] = s_window[from++];
|
||||
} while (--op);
|
||||
from = _out - dist; /* rest from output */
|
||||
from_source = output;
|
||||
}
|
||||
}
|
||||
while (len > 2) {
|
||||
output[_out++] = from_source[from++];
|
||||
output[_out++] = from_source[from++];
|
||||
output[_out++] = from_source[from++];
|
||||
len -= 3;
|
||||
}
|
||||
if (len) {
|
||||
output[_out++] = from_source[from++];
|
||||
if (len > 1) {
|
||||
output[_out++] = from_source[from++];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
from = _out - dist; /* copy direct from output */
|
||||
do { /* minimum length is three */
|
||||
output[_out++] = output[from++];
|
||||
output[_out++] = output[from++];
|
||||
output[_out++] = output[from++];
|
||||
len -= 3;
|
||||
} while (len > 2);
|
||||
if (len) {
|
||||
output[_out++] = output[from++];
|
||||
if (len > 1) {
|
||||
output[_out++] = output[from++];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((op & 64) === 0) { /* 2nd level distance code */
|
||||
here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];
|
||||
continue dodist;
|
||||
}
|
||||
else {
|
||||
strm.msg = 'invalid distance code';
|
||||
state.mode = BAD;
|
||||
break top;
|
||||
}
|
||||
|
||||
break; // need to emulate goto via "continue"
|
||||
}
|
||||
}
|
||||
else if ((op & 64) === 0) { /* 2nd level length code */
|
||||
here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];
|
||||
continue dolen;
|
||||
}
|
||||
else if (op & 32) { /* end-of-block */
|
||||
//Tracevv((stderr, "inflate: end of block\n"));
|
||||
state.mode = TYPE;
|
||||
break top;
|
||||
}
|
||||
else {
|
||||
strm.msg = 'invalid literal/length code';
|
||||
state.mode = BAD;
|
||||
break top;
|
||||
}
|
||||
|
||||
break; // need to emulate goto via "continue"
|
||||
}
|
||||
} while (_in < last && _out < end);
|
||||
|
||||
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
|
||||
len = bits >> 3;
|
||||
_in -= len;
|
||||
bits -= len << 3;
|
||||
hold &= (1 << bits) - 1;
|
||||
|
||||
/* update state and return */
|
||||
strm.next_in = _in;
|
||||
strm.next_out = _out;
|
||||
strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last));
|
||||
strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end));
|
||||
state.hold = hold;
|
||||
state.bits = bits;
|
||||
return;
|
||||
};
|
1527
public/novnc/vendor/pako/lib/zlib/inflate.js
vendored
Normal file
322
public/novnc/vendor/pako/lib/zlib/inftrees.js
vendored
Normal file
@ -0,0 +1,322 @@
|
||||
import * as utils from "../utils/common.js";
|
||||
|
||||
var MAXBITS = 15;
|
||||
var ENOUGH_LENS = 852;
|
||||
var ENOUGH_DISTS = 592;
|
||||
//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
|
||||
|
||||
var CODES = 0;
|
||||
var LENS = 1;
|
||||
var DISTS = 2;
|
||||
|
||||
var lbase = [ /* Length codes 257..285 base */
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
|
||||
];
|
||||
|
||||
var lext = [ /* Length codes 257..285 extra */
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78
|
||||
];
|
||||
|
||||
var dbase = [ /* Distance codes 0..29 base */
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||
8193, 12289, 16385, 24577, 0, 0
|
||||
];
|
||||
|
||||
var dext = [ /* Distance codes 0..29 extra */
|
||||
16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
|
||||
23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
|
||||
28, 28, 29, 29, 64, 64
|
||||
];
|
||||
|
||||
export default function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts)
|
||||
{
|
||||
var bits = opts.bits;
|
||||
//here = opts.here; /* table entry for duplication */
|
||||
|
||||
var len = 0; /* a code's length in bits */
|
||||
var sym = 0; /* index of code symbols */
|
||||
var min = 0, max = 0; /* minimum and maximum code lengths */
|
||||
var root = 0; /* number of index bits for root table */
|
||||
var curr = 0; /* number of index bits for current table */
|
||||
var drop = 0; /* code bits to drop for sub-table */
|
||||
var left = 0; /* number of prefix codes available */
|
||||
var used = 0; /* code entries in table used */
|
||||
var huff = 0; /* Huffman code */
|
||||
var incr; /* for incrementing code, index */
|
||||
var fill; /* index for replicating entries */
|
||||
var low; /* low bits for current root entry */
|
||||
var mask; /* mask for low root bits */
|
||||
var next; /* next available space in table */
|
||||
var base = null; /* base value table to use */
|
||||
var base_index = 0;
|
||||
// var shoextra; /* extra bits table to use */
|
||||
var end; /* use base and extra for symbol > end */
|
||||
var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */
|
||||
var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */
|
||||
var extra = null;
|
||||
var extra_index = 0;
|
||||
|
||||
var here_bits, here_op, here_val;
|
||||
|
||||
/*
|
||||
Process a set of code lengths to create a canonical Huffman code. The
|
||||
code lengths are lens[0..codes-1]. Each length corresponds to the
|
||||
symbols 0..codes-1. The Huffman code is generated by first sorting the
|
||||
symbols by length from short to long, and retaining the symbol order
|
||||
for codes with equal lengths. Then the code starts with all zero bits
|
||||
for the first code of the shortest length, and the codes are integer
|
||||
increments for the same length, and zeros are appended as the length
|
||||
increases. For the deflate format, these bits are stored backwards
|
||||
from their more natural integer increment ordering, and so when the
|
||||
decoding tables are built in the large loop below, the integer codes
|
||||
are incremented backwards.
|
||||
|
||||
This routine assumes, but does not check, that all of the entries in
|
||||
lens[] are in the range 0..MAXBITS. The caller must assure this.
|
||||
1..MAXBITS is interpreted as that code length. zero means that that
|
||||
symbol does not occur in this code.
|
||||
|
||||
The codes are sorted by computing a count of codes for each length,
|
||||
creating from that a table of starting indices for each length in the
|
||||
sorted table, and then entering the symbols in order in the sorted
|
||||
table. The sorted table is work[], with that space being provided by
|
||||
the caller.
|
||||
|
||||
The length counts are used for other purposes as well, i.e. finding
|
||||
the minimum and maximum length codes, determining if there are any
|
||||
codes at all, checking for a valid set of lengths, and looking ahead
|
||||
at length counts to determine sub-table sizes when building the
|
||||
decoding tables.
|
||||
*/
|
||||
|
||||
/* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
|
||||
for (len = 0; len <= MAXBITS; len++) {
|
||||
count[len] = 0;
|
||||
}
|
||||
for (sym = 0; sym < codes; sym++) {
|
||||
count[lens[lens_index + sym]]++;
|
||||
}
|
||||
|
||||
/* bound code lengths, force root to be within code lengths */
|
||||
root = bits;
|
||||
for (max = MAXBITS; max >= 1; max--) {
|
||||
if (count[max] !== 0) { break; }
|
||||
}
|
||||
if (root > max) {
|
||||
root = max;
|
||||
}
|
||||
if (max === 0) { /* no symbols to code at all */
|
||||
//table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */
|
||||
//table.bits[opts.table_index] = 1; //here.bits = (var char)1;
|
||||
//table.val[opts.table_index++] = 0; //here.val = (var short)0;
|
||||
table[table_index++] = (1 << 24) | (64 << 16) | 0;
|
||||
|
||||
|
||||
//table.op[opts.table_index] = 64;
|
||||
//table.bits[opts.table_index] = 1;
|
||||
//table.val[opts.table_index++] = 0;
|
||||
table[table_index++] = (1 << 24) | (64 << 16) | 0;
|
||||
|
||||
opts.bits = 1;
|
||||
return 0; /* no symbols, but wait for decoding to report error */
|
||||
}
|
||||
for (min = 1; min < max; min++) {
|
||||
if (count[min] !== 0) { break; }
|
||||
}
|
||||
if (root < min) {
|
||||
root = min;
|
||||
}
|
||||
|
||||
/* check for an over-subscribed or incomplete set of lengths */
|
||||
left = 1;
|
||||
for (len = 1; len <= MAXBITS; len++) {
|
||||
left <<= 1;
|
||||
left -= count[len];
|
||||
if (left < 0) {
|
||||
return -1;
|
||||
} /* over-subscribed */
|
||||
}
|
||||
if (left > 0 && (type === CODES || max !== 1)) {
|
||||
return -1; /* incomplete set */
|
||||
}
|
||||
|
||||
/* generate offsets into symbol table for each length for sorting */
|
||||
offs[1] = 0;
|
||||
for (len = 1; len < MAXBITS; len++) {
|
||||
offs[len + 1] = offs[len] + count[len];
|
||||
}
|
||||
|
||||
/* sort symbols by length, by symbol order within each length */
|
||||
for (sym = 0; sym < codes; sym++) {
|
||||
if (lens[lens_index + sym] !== 0) {
|
||||
work[offs[lens[lens_index + sym]]++] = sym;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Create and fill in decoding tables. In this loop, the table being
|
||||
filled is at next and has curr index bits. The code being used is huff
|
||||
with length len. That code is converted to an index by dropping drop
|
||||
bits off of the bottom. For codes where len is less than drop + curr,
|
||||
those top drop + curr - len bits are incremented through all values to
|
||||
fill the table with replicated entries.
|
||||
|
||||
root is the number of index bits for the root table. When len exceeds
|
||||
root, sub-tables are created pointed to by the root entry with an index
|
||||
of the low root bits of huff. This is saved in low to check for when a
|
||||
new sub-table should be started. drop is zero when the root table is
|
||||
being filled, and drop is root when sub-tables are being filled.
|
||||
|
||||
When a new sub-table is needed, it is necessary to look ahead in the
|
||||
code lengths to determine what size sub-table is needed. The length
|
||||
counts are used for this, and so count[] is decremented as codes are
|
||||
entered in the tables.
|
||||
|
||||
used keeps track of how many table entries have been allocated from the
|
||||
provided *table space. It is checked for LENS and DIST tables against
|
||||
the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
|
||||
the initial root table size constants. See the comments in inftrees.h
|
||||
for more information.
|
||||
|
||||
sym increments through all symbols, and the loop terminates when
|
||||
all codes of length max, i.e. all codes, have been processed. This
|
||||
routine permits incomplete codes, so another loop after this one fills
|
||||
in the rest of the decoding tables with invalid code markers.
|
||||
*/
|
||||
|
||||
/* set up for code type */
|
||||
// poor man optimization - use if-else instead of switch,
|
||||
// to avoid deopts in old v8
|
||||
if (type === CODES) {
|
||||
base = extra = work; /* dummy value--not used */
|
||||
end = 19;
|
||||
|
||||
} else if (type === LENS) {
|
||||
base = lbase;
|
||||
base_index -= 257;
|
||||
extra = lext;
|
||||
extra_index -= 257;
|
||||
end = 256;
|
||||
|
||||
} else { /* DISTS */
|
||||
base = dbase;
|
||||
extra = dext;
|
||||
end = -1;
|
||||
}
|
||||
|
||||
/* initialize opts for loop */
|
||||
huff = 0; /* starting code */
|
||||
sym = 0; /* starting code symbol */
|
||||
len = min; /* starting code length */
|
||||
next = table_index; /* current table to fill in */
|
||||
curr = root; /* current table index bits */
|
||||
drop = 0; /* current bits to drop from code for index */
|
||||
low = -1; /* trigger new sub-table when len > root */
|
||||
used = 1 << root; /* use root table entries */
|
||||
mask = used - 1; /* mask for comparing low */
|
||||
|
||||
/* check available table space */
|
||||
if ((type === LENS && used > ENOUGH_LENS) ||
|
||||
(type === DISTS && used > ENOUGH_DISTS)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* process all codes and make table entries */
|
||||
for (;;) {
|
||||
/* create table entry */
|
||||
here_bits = len - drop;
|
||||
if (work[sym] < end) {
|
||||
here_op = 0;
|
||||
here_val = work[sym];
|
||||
}
|
||||
else if (work[sym] > end) {
|
||||
here_op = extra[extra_index + work[sym]];
|
||||
here_val = base[base_index + work[sym]];
|
||||
}
|
||||
else {
|
||||
here_op = 32 + 64; /* end of block */
|
||||
here_val = 0;
|
||||
}
|
||||
|
||||
/* replicate for those indices with low len bits equal to huff */
|
||||
incr = 1 << (len - drop);
|
||||
fill = 1 << curr;
|
||||
min = fill; /* save offset to next table */
|
||||
do {
|
||||
fill -= incr;
|
||||
table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0;
|
||||
} while (fill !== 0);
|
||||
|
||||
/* backwards increment the len-bit code huff */
|
||||
incr = 1 << (len - 1);
|
||||
while (huff & incr) {
|
||||
incr >>= 1;
|
||||
}
|
||||
if (incr !== 0) {
|
||||
huff &= incr - 1;
|
||||
huff += incr;
|
||||
} else {
|
||||
huff = 0;
|
||||
}
|
||||
|
||||
/* go to next symbol, update count, len */
|
||||
sym++;
|
||||
if (--count[len] === 0) {
|
||||
if (len === max) { break; }
|
||||
len = lens[lens_index + work[sym]];
|
||||
}
|
||||
|
||||
/* create new sub-table if needed */
|
||||
if (len > root && (huff & mask) !== low) {
|
||||
/* if first time, transition to sub-tables */
|
||||
if (drop === 0) {
|
||||
drop = root;
|
||||
}
|
||||
|
||||
/* increment past last table */
|
||||
next += min; /* here min is 1 << curr */
|
||||
|
||||
/* determine length of next table */
|
||||
curr = len - drop;
|
||||
left = 1 << curr;
|
||||
while (curr + drop < max) {
|
||||
left -= count[curr + drop];
|
||||
if (left <= 0) { break; }
|
||||
curr++;
|
||||
left <<= 1;
|
||||
}
|
||||
|
||||
/* check for enough space */
|
||||
used += 1 << curr;
|
||||
if ((type === LENS && used > ENOUGH_LENS) ||
|
||||
(type === DISTS && used > ENOUGH_DISTS)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* point entry in root table to sub-table */
|
||||
low = huff & mask;
|
||||
/*table.op[low] = curr;
|
||||
table.bits[low] = root;
|
||||
table.val[low] = next - opts.table_index;*/
|
||||
table[low] = (root << 24) | (curr << 16) | (next - table_index) |0;
|
||||
}
|
||||
}
|
||||
|
||||
/* fill in remaining table entry if code is incomplete (guaranteed to have
|
||||
at most one remaining entry, since if the code is incomplete, the
|
||||
maximum code length that was allowed to get this far is one bit) */
|
||||
if (huff !== 0) {
|
||||
//table.op[next + huff] = 64; /* invalid code marker */
|
||||
//table.bits[next + huff] = len - drop;
|
||||
//table.val[next + huff] = 0;
|
||||
table[next + huff] = ((len - drop) << 24) | (64 << 16) |0;
|
||||
}
|
||||
|
||||
/* set return parameters */
|
||||
//opts.table_index += used;
|
||||
opts.bits = root;
|
||||
return 0;
|
||||
};
|
11
public/novnc/vendor/pako/lib/zlib/messages.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
export default {
|
||||
2: 'need dictionary', /* Z_NEED_DICT 2 */
|
||||
1: 'stream end', /* Z_STREAM_END 1 */
|
||||
0: '', /* Z_OK 0 */
|
||||
'-1': 'file error', /* Z_ERRNO (-1) */
|
||||
'-2': 'stream error', /* Z_STREAM_ERROR (-2) */
|
||||
'-3': 'data error', /* Z_DATA_ERROR (-3) */
|
||||
'-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */
|
||||
'-5': 'buffer error', /* Z_BUF_ERROR (-5) */
|
||||
'-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */
|
||||
};
|
1195
public/novnc/vendor/pako/lib/zlib/trees.js
vendored
Normal file
24
public/novnc/vendor/pako/lib/zlib/zstream.js
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
export default function ZStream() {
|
||||
/* next input byte */
|
||||
this.input = null; // JS specific, because we have no pointers
|
||||
this.next_in = 0;
|
||||
/* number of bytes available at input */
|
||||
this.avail_in = 0;
|
||||
/* total number of input bytes read so far */
|
||||
this.total_in = 0;
|
||||
/* next output byte should be put there */
|
||||
this.output = null; // JS specific, because we have no pointers
|
||||
this.next_out = 0;
|
||||
/* remaining free space at output */
|
||||
this.avail_out = 0;
|
||||
/* total number of bytes output so far */
|
||||
this.total_out = 0;
|
||||
/* last error message, NULL if no error */
|
||||
this.msg = ''/*Z_NULL*/;
|
||||
/* not visible by applications */
|
||||
this.state = null;
|
||||
/* best guess about the data type: binary or text */
|
||||
this.data_type = 2/*Z_UNKNOWN*/;
|
||||
/* adler32 value of the uncompressed data */
|
||||
this.adler = 0;
|
||||
}
|
255
public/novnc/vendor/promise.js
vendored
Normal file
@ -0,0 +1,255 @@
|
||||
/* Copyright (c) 2014 Taylor Hakes
|
||||
* Copyright (c) 2014 Forbes Lindesay
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
(function (root) {
|
||||
|
||||
// Store setTimeout reference so promise-polyfill will be unaffected by
|
||||
// other code modifying setTimeout (like sinon.useFakeTimers())
|
||||
var setTimeoutFunc = setTimeout;
|
||||
|
||||
function noop() {}
|
||||
|
||||
// Polyfill for Function.prototype.bind
|
||||
function bind(fn, thisArg) {
|
||||
return function () {
|
||||
fn.apply(thisArg, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
function Promise(fn) {
|
||||
if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new');
|
||||
if (typeof fn !== 'function') throw new TypeError('not a function');
|
||||
this._state = 0;
|
||||
this._handled = false;
|
||||
this._value = undefined;
|
||||
this._deferreds = [];
|
||||
|
||||
doResolve(fn, this);
|
||||
}
|
||||
|
||||
function handle(self, deferred) {
|
||||
while (self._state === 3) {
|
||||
self = self._value;
|
||||
}
|
||||
if (self._state === 0) {
|
||||
self._deferreds.push(deferred);
|
||||
return;
|
||||
}
|
||||
self._handled = true;
|
||||
Promise._immediateFn(function () {
|
||||
var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
|
||||
if (cb === null) {
|
||||
(self._state === 1 ? resolve : reject)(deferred.promise, self._value);
|
||||
return;
|
||||
}
|
||||
var ret;
|
||||
try {
|
||||
ret = cb(self._value);
|
||||
} catch (e) {
|
||||
reject(deferred.promise, e);
|
||||
return;
|
||||
}
|
||||
resolve(deferred.promise, ret);
|
||||
});
|
||||
}
|
||||
|
||||
function resolve(self, newValue) {
|
||||
try {
|
||||
// Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
|
||||
if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.');
|
||||
if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
|
||||
var then = newValue.then;
|
||||
if (newValue instanceof Promise) {
|
||||
self._state = 3;
|
||||
self._value = newValue;
|
||||
finale(self);
|
||||
return;
|
||||
} else if (typeof then === 'function') {
|
||||
doResolve(bind(then, newValue), self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
self._state = 1;
|
||||
self._value = newValue;
|
||||
finale(self);
|
||||
} catch (e) {
|
||||
reject(self, e);
|
||||
}
|
||||
}
|
||||
|
||||
function reject(self, newValue) {
|
||||
self._state = 2;
|
||||
self._value = newValue;
|
||||
finale(self);
|
||||
}
|
||||
|
||||
function finale(self) {
|
||||
if (self._state === 2 && self._deferreds.length === 0) {
|
||||
Promise._immediateFn(function() {
|
||||
if (!self._handled) {
|
||||
Promise._unhandledRejectionFn(self._value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (var i = 0, len = self._deferreds.length; i < len; i++) {
|
||||
handle(self, self._deferreds[i]);
|
||||
}
|
||||
self._deferreds = null;
|
||||
}
|
||||
|
||||
function Handler(onFulfilled, onRejected, promise) {
|
||||
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
|
||||
this.onRejected = typeof onRejected === 'function' ? onRejected : null;
|
||||
this.promise = promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a potentially misbehaving resolver function and make sure
|
||||
* onFulfilled and onRejected are only called once.
|
||||
*
|
||||
* Makes no guarantees about asynchrony.
|
||||
*/
|
||||
function doResolve(fn, self) {
|
||||
var done = false;
|
||||
try {
|
||||
fn(function (value) {
|
||||
if (done) return;
|
||||
done = true;
|
||||
resolve(self, value);
|
||||
}, function (reason) {
|
||||
if (done) return;
|
||||
done = true;
|
||||
reject(self, reason);
|
||||
});
|
||||
} catch (ex) {
|
||||
if (done) return;
|
||||
done = true;
|
||||
reject(self, ex);
|
||||
}
|
||||
}
|
||||
|
||||
Promise.prototype['catch'] = function (onRejected) {
|
||||
return this.then(null, onRejected);
|
||||
};
|
||||
|
||||
Promise.prototype.then = function (onFulfilled, onRejected) {
|
||||
var prom = new (this.constructor)(noop);
|
||||
|
||||
handle(this, new Handler(onFulfilled, onRejected, prom));
|
||||
return prom;
|
||||
};
|
||||
|
||||
Promise.all = function (arr) {
|
||||
var args = Array.prototype.slice.call(arr);
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (args.length === 0) return resolve([]);
|
||||
var remaining = args.length;
|
||||
|
||||
function res(i, val) {
|
||||
try {
|
||||
if (val && (typeof val === 'object' || typeof val === 'function')) {
|
||||
var then = val.then;
|
||||
if (typeof then === 'function') {
|
||||
then.call(val, function (val) {
|
||||
res(i, val);
|
||||
}, reject);
|
||||
return;
|
||||
}
|
||||
}
|
||||
args[i] = val;
|
||||
if (--remaining === 0) {
|
||||
resolve(args);
|
||||
}
|
||||
} catch (ex) {
|
||||
reject(ex);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
res(i, args[i]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Promise.resolve = function (value) {
|
||||
if (value && typeof value === 'object' && value.constructor === Promise) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return new Promise(function (resolve) {
|
||||
resolve(value);
|
||||
});
|
||||
};
|
||||
|
||||
Promise.reject = function (value) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
reject(value);
|
||||
});
|
||||
};
|
||||
|
||||
Promise.race = function (values) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
for (var i = 0, len = values.length; i < len; i++) {
|
||||
values[i].then(resolve, reject);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Use polyfill for setImmediate for performance gains
|
||||
Promise._immediateFn = (typeof setImmediate === 'function' && function (fn) { setImmediate(fn); }) ||
|
||||
function (fn) {
|
||||
setTimeoutFunc(fn, 0);
|
||||
};
|
||||
|
||||
Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {
|
||||
if (typeof console !== 'undefined' && console) {
|
||||
console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the immediate function to execute callbacks
|
||||
* @param fn {function} Function to execute
|
||||
* @deprecated
|
||||
*/
|
||||
Promise._setImmediateFn = function _setImmediateFn(fn) {
|
||||
Promise._immediateFn = fn;
|
||||
};
|
||||
|
||||
/**
|
||||
* Change the function to execute on unhandled rejection
|
||||
* @param {function} fn Function to execute on unhandled rejection
|
||||
* @deprecated
|
||||
*/
|
||||
Promise._setUnhandledRejectionFn = function _setUnhandledRejectionFn(fn) {
|
||||
Promise._unhandledRejectionFn = fn;
|
||||
};
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = Promise;
|
||||
} else if (!root.Promise) {
|
||||
root.Promise = Promise;
|
||||
}
|
||||
|
||||
})(this);
|