mirror of
https://gitee.com/gfdgd-xi/deep-wine-runner
synced 2025-12-14 19:12:04 +08:00
完善虚拟机连接
This commit is contained in:
14
VM/novnc/utils/README.md
Normal file
14
VM/novnc/utils/README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
## WebSockets Proxy/Bridge
|
||||
|
||||
Websockify has been forked out into its own project. `novnc_proxy` will
|
||||
automatically download it here if it is not already present and not
|
||||
installed as system-wide.
|
||||
|
||||
For more detailed description and usage information please refer to
|
||||
the [websockify README](https://github.com/novnc/websockify/blob/master/README.md).
|
||||
|
||||
The other versions of websockify (C, Node.js) and the associated test
|
||||
programs have been moved to
|
||||
[websockify](https://github.com/novnc/websockify). Websockify was
|
||||
formerly named wsproxy.
|
||||
|
||||
17
VM/novnc/utils/b64-to-binary.pl
Executable file
17
VM/novnc/utils/b64-to-binary.pl
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env perl
|
||||
use MIME::Base64;
|
||||
|
||||
for (<>) {
|
||||
unless (/^'([{}])(\d+)\1(.+?)',$/) {
|
||||
print;
|
||||
next;
|
||||
}
|
||||
|
||||
my ($dir, $amt, $b64) = ($1, $2, $3);
|
||||
|
||||
my $decoded = MIME::Base64::decode($b64) or die "Could not base64-decode line `$_`";
|
||||
|
||||
my $decoded_escaped = join "", map { "\\x$_" } unpack("(H2)*", $decoded);
|
||||
|
||||
print "'${dir}${amt}${dir}${decoded_escaped}',\n";
|
||||
}
|
||||
140
VM/novnc/utils/convert.js
Executable file
140
VM/novnc/utils/convert.js
Executable file
@@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const path = require('path');
|
||||
const { program } = require('commander');
|
||||
const fs = require('fs');
|
||||
const fse = require('fs-extra');
|
||||
const babel = require('@babel/core');
|
||||
|
||||
program
|
||||
.option('-m, --with-source-maps [type]', 'output source maps when not generating a bundled app (type may be empty for external source maps, inline for inline source maps, or both) ')
|
||||
.option('--clean', 'clear the lib folder before building')
|
||||
.parse(process.argv);
|
||||
|
||||
// the various important paths
|
||||
const paths = {
|
||||
main: path.resolve(__dirname, '..'),
|
||||
core: path.resolve(__dirname, '..', 'core'),
|
||||
vendor: path.resolve(__dirname, '..', 'vendor'),
|
||||
libDirBase: path.resolve(__dirname, '..', 'lib'),
|
||||
};
|
||||
|
||||
// util.promisify requires Node.js 8.x, so we have our own
|
||||
function promisify(original) {
|
||||
return function promiseWrap() {
|
||||
const args = Array.prototype.slice.call(arguments);
|
||||
return new Promise((resolve, reject) => {
|
||||
original.apply(this, args.concat((err, value) => {
|
||||
if (err) return reject(err);
|
||||
resolve(value);
|
||||
}));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
const writeFile = promisify(fs.writeFile);
|
||||
|
||||
const readdir = promisify(fs.readdir);
|
||||
const lstat = promisify(fs.lstat);
|
||||
|
||||
const ensureDir = promisify(fse.ensureDir);
|
||||
|
||||
const babelTransformFile = promisify(babel.transformFile);
|
||||
|
||||
// walkDir *recursively* walks directories trees,
|
||||
// calling the callback for all normal files found.
|
||||
function walkDir(basePath, cb, filter) {
|
||||
return readdir(basePath)
|
||||
.then((files) => {
|
||||
const paths = files.map(filename => path.join(basePath, filename));
|
||||
return Promise.all(paths.map(filepath => lstat(filepath)
|
||||
.then((stats) => {
|
||||
if (filter !== undefined && !filter(filepath, stats)) return;
|
||||
|
||||
if (stats.isSymbolicLink()) return;
|
||||
if (stats.isFile()) return cb(filepath);
|
||||
if (stats.isDirectory()) return walkDir(filepath, cb, filter);
|
||||
})));
|
||||
});
|
||||
}
|
||||
|
||||
function makeLibFiles(sourceMaps) {
|
||||
// NB: we need to make a copy of babelOpts, since babel sets some defaults on it
|
||||
const babelOpts = () => ({
|
||||
plugins: [],
|
||||
presets: [
|
||||
[ '@babel/preset-env',
|
||||
{ modules: 'commonjs' } ]
|
||||
],
|
||||
ast: false,
|
||||
sourceMaps: sourceMaps,
|
||||
});
|
||||
|
||||
fse.ensureDirSync(paths.libDirBase);
|
||||
|
||||
const outFiles = [];
|
||||
|
||||
const handleDir = (vendorRewrite, inPathBase, filename) => Promise.resolve()
|
||||
.then(() => {
|
||||
const outPath = path.join(paths.libDirBase, path.relative(inPathBase, filename));
|
||||
|
||||
if (path.extname(filename) !== '.js') {
|
||||
return; // skip non-javascript files
|
||||
}
|
||||
return Promise.resolve()
|
||||
.then(() => ensureDir(path.dirname(outPath)))
|
||||
.then(() => {
|
||||
const opts = babelOpts();
|
||||
// Adjust for the fact that we move the core files relative
|
||||
// to the vendor directory
|
||||
if (vendorRewrite) {
|
||||
opts.plugins.push(["import-redirect",
|
||||
{"root": paths.libDirBase,
|
||||
"redirect": { "vendor/(.+)": "./vendor/$1"}}]);
|
||||
}
|
||||
|
||||
return babelTransformFile(filename, opts)
|
||||
.then((res) => {
|
||||
console.log(`Writing ${outPath}`);
|
||||
const {map} = res;
|
||||
let {code} = res;
|
||||
if (sourceMaps === true) {
|
||||
// append URL for external source map
|
||||
code += `\n//# sourceMappingURL=${path.basename(outPath)}.map\n`;
|
||||
}
|
||||
outFiles.push(`${outPath}`);
|
||||
return writeFile(outPath, code)
|
||||
.then(() => {
|
||||
if (sourceMaps === true || sourceMaps === 'both') {
|
||||
console.log(` and ${outPath}.map`);
|
||||
outFiles.push(`${outPath}.map`);
|
||||
return writeFile(`${outPath}.map`, JSON.stringify(map));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Promise.resolve()
|
||||
.then(() => {
|
||||
const handler = handleDir.bind(null, false, paths.main);
|
||||
return walkDir(paths.vendor, handler);
|
||||
})
|
||||
.then(() => {
|
||||
const handler = handleDir.bind(null, true, paths.core);
|
||||
return walkDir(paths.core, handler);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(`Failure converting modules: ${err}`);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
let options = program.opts();
|
||||
|
||||
if (options.clean) {
|
||||
console.log(`Removing ${paths.libDirBase}`);
|
||||
fse.removeSync(paths.libDirBase);
|
||||
}
|
||||
|
||||
makeLibFiles(options.withSourceMaps);
|
||||
127
VM/novnc/utils/genkeysymdef.js
Executable file
127
VM/novnc/utils/genkeysymdef.js
Executable file
@@ -0,0 +1,127 @@
|
||||
#!/usr/bin/env node
|
||||
/*
|
||||
* genkeysymdef: X11 keysymdef.h to JavaScript converter
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
let showHelp = process.argv.length === 2;
|
||||
let filename;
|
||||
|
||||
for (let i = 2; i < process.argv.length; ++i) {
|
||||
switch (process.argv[i]) {
|
||||
case "--help":
|
||||
case "-h":
|
||||
showHelp = true;
|
||||
break;
|
||||
case "--file":
|
||||
case "-f":
|
||||
default:
|
||||
filename = process.argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!filename) {
|
||||
showHelp = true;
|
||||
console.log("Error: No filename specified\n");
|
||||
}
|
||||
|
||||
if (showHelp) {
|
||||
console.log("Parses a *nix keysymdef.h to generate Unicode code point mappings");
|
||||
console.log("Usage: node parse.js [options] filename:");
|
||||
console.log(" -h [ --help ] Produce this help message");
|
||||
console.log(" filename The keysymdef.h file to parse");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const buf = fs.readFileSync(filename);
|
||||
const str = buf.toString('utf8');
|
||||
|
||||
const re = /^#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-fA-F]+)\s*(\/\*\s*(.*)\s*\*\/)?\s*$/m;
|
||||
|
||||
const arr = str.split('\n');
|
||||
|
||||
const codepoints = {};
|
||||
|
||||
for (let i = 0; i < arr.length; ++i) {
|
||||
const result = re.exec(arr[i]);
|
||||
if (result) {
|
||||
const keyname = result[1];
|
||||
const keysym = parseInt(result[2], 16);
|
||||
const remainder = result[3];
|
||||
|
||||
const unicodeRes = /U\+([0-9a-fA-F]+)/.exec(remainder);
|
||||
if (unicodeRes) {
|
||||
const unicode = parseInt(unicodeRes[1], 16);
|
||||
// The first entry is the preferred one
|
||||
if (!codepoints[unicode]) {
|
||||
codepoints[unicode] = { keysym: keysym, name: keyname };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let out =
|
||||
"/*\n" +
|
||||
" * Mapping from Unicode codepoints to X11/RFB keysyms\n" +
|
||||
" *\n" +
|
||||
" * This file was automatically generated from keysymdef.h\n" +
|
||||
" * DO NOT EDIT!\n" +
|
||||
" */\n" +
|
||||
"\n" +
|
||||
"/* Functions at the bottom */\n" +
|
||||
"\n" +
|
||||
"const codepoints = {\n";
|
||||
|
||||
function toHex(num) {
|
||||
let s = num.toString(16);
|
||||
if (s.length < 4) {
|
||||
s = ("0000" + s).slice(-4);
|
||||
}
|
||||
return "0x" + s;
|
||||
}
|
||||
|
||||
for (let codepoint in codepoints) {
|
||||
codepoint = parseInt(codepoint);
|
||||
|
||||
// Latin-1?
|
||||
if ((codepoint >= 0x20) && (codepoint <= 0xff)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handled by the general Unicode mapping?
|
||||
if ((codepoint | 0x01000000) === codepoints[codepoint].keysym) {
|
||||
continue;
|
||||
}
|
||||
|
||||
out += " " + toHex(codepoint) + ": " +
|
||||
toHex(codepoints[codepoint].keysym) +
|
||||
", // XK_" + codepoints[codepoint].name + "\n";
|
||||
}
|
||||
|
||||
out +=
|
||||
"};\n" +
|
||||
"\n" +
|
||||
"export default {\n" +
|
||||
" lookup(u) {\n" +
|
||||
" // Latin-1 is one-to-one mapping\n" +
|
||||
" if ((u >= 0x20) && (u <= 0xff)) {\n" +
|
||||
" return u;\n" +
|
||||
" }\n" +
|
||||
"\n" +
|
||||
" // Lookup table (fairly random)\n" +
|
||||
" const keysym = codepoints[u];\n" +
|
||||
" if (keysym !== undefined) {\n" +
|
||||
" return keysym;\n" +
|
||||
" }\n" +
|
||||
"\n" +
|
||||
" // General mapping as final fallback\n" +
|
||||
" return 0x01000000 | u;\n" +
|
||||
" },\n" +
|
||||
"};";
|
||||
|
||||
console.log(out);
|
||||
234
VM/novnc/utils/novnc_proxy
Executable file
234
VM/novnc/utils/novnc_proxy
Executable file
@@ -0,0 +1,234 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (C) 2018 The noVNC Authors
|
||||
# Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||
|
||||
usage() {
|
||||
if [ "$*" ]; then
|
||||
echo "$*"
|
||||
echo
|
||||
fi
|
||||
echo "Usage: ${NAME} [--listen [HOST:]PORT] [--vnc VNC_HOST:PORT] [--cert CERT] [--ssl-only]"
|
||||
echo
|
||||
echo "Starts the WebSockets proxy and a mini-webserver and "
|
||||
echo "provides a cut-and-paste URL to go to."
|
||||
echo
|
||||
echo " --listen [HOST:]PORT Port for proxy/webserver to listen on"
|
||||
echo " Default: 6080 (on all interfaces)"
|
||||
echo " --vnc VNC_HOST:PORT VNC server host:port proxy target"
|
||||
echo " Default: localhost:5900"
|
||||
echo " --cert CERT Path to combined cert/key file, or just"
|
||||
echo " the cert file if used with --key"
|
||||
echo " Default: self.pem"
|
||||
echo " --key KEY Path to key file, when not combined with cert"
|
||||
echo " --web WEB Path to web files (e.g. vnc.html)"
|
||||
echo " Default: ./"
|
||||
echo " --ssl-only Disable non-https connections."
|
||||
echo " "
|
||||
echo " --file-only Disable directory listing in web server."
|
||||
echo " "
|
||||
echo " --record FILE Record traffic to FILE.session.js"
|
||||
echo " "
|
||||
echo " --syslog SERVER Can be local socket such as /dev/log, or a UDP host:port pair."
|
||||
echo " "
|
||||
echo " --heartbeat SEC send a ping to the client every SEC seconds"
|
||||
echo " --timeout SEC after SEC seconds exit when not connected"
|
||||
echo " --idle-timeout SEC server exits after SEC seconds if there are no"
|
||||
echo " "
|
||||
echo " --web-auth enable authentication"
|
||||
echo " --auth-plugin CLASS authentication plugin to use"
|
||||
echo " --auth-source ARG plugin configuration"
|
||||
echo " "
|
||||
echo " active connections"
|
||||
echo " "
|
||||
exit 2
|
||||
}
|
||||
|
||||
NAME="$(basename $0)"
|
||||
REAL_NAME="$(readlink -f $0)"
|
||||
HERE="$(cd "$(dirname "$REAL_NAME")" && pwd)"
|
||||
HOST=""
|
||||
PORT="6080"
|
||||
LISTEN="$PORT"
|
||||
VNC_DEST="localhost:5900"
|
||||
CERT=""
|
||||
KEY=""
|
||||
WEB=""
|
||||
proxy_pid=""
|
||||
SSLONLY=""
|
||||
RECORD=""
|
||||
SYSLOG_ARG=""
|
||||
HEARTBEAT_ARG=""
|
||||
IDLETIMEOUT_ARG=""
|
||||
TIMEOUT_ARG=""
|
||||
WEBAUTH_ARG=""
|
||||
AUTHPLUGIN_ARG=""
|
||||
AUTHSOURCE_ARG=""
|
||||
FILEONLY_ARG=""
|
||||
|
||||
|
||||
die() {
|
||||
echo "$*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
trap - TERM QUIT INT EXIT
|
||||
trap "true" CHLD # Ignore cleanup messages
|
||||
echo
|
||||
if [ -n "${proxy_pid}" ]; then
|
||||
echo "Terminating WebSockets proxy (${proxy_pid})"
|
||||
kill ${proxy_pid}
|
||||
fi
|
||||
}
|
||||
|
||||
# Process Arguments
|
||||
|
||||
# Arguments that only apply to chrooter itself
|
||||
while [ "$*" ]; do
|
||||
param=$1; shift; OPTARG=$1
|
||||
case $param in
|
||||
--listen) LISTEN="${OPTARG}"; shift ;;
|
||||
--vnc) VNC_DEST="${OPTARG}"; shift ;;
|
||||
--cert) CERT="${OPTARG}"; shift ;;
|
||||
--key) KEY="${OPTARG}"; shift ;;
|
||||
--web) WEB="${OPTARG}"; shift ;;
|
||||
--ssl-only) SSLONLY="--ssl-only" ;;
|
||||
--file-only) FILEONLY_ARG="--file-only" ;;
|
||||
--record) RECORD="${OPTARG}"; shift ;;
|
||||
--syslog) SYSLOG_ARG="--syslog ${OPTARG}"; shift ;;
|
||||
--heartbeat) HEARTBEAT_ARG="--heartbeat ${OPTARG}"; shift ;;
|
||||
--idle-timeout) IDLETIMEOUT_ARG="--idle-timeout ${OPTARG}"; shift ;;
|
||||
--timeout) TIMEOUT_ARG="--timeout ${OPTARG}"; shift ;;
|
||||
--web-auth) WEBAUTH_ARG="--web-auth" ;;
|
||||
--auth-plugin) AUTHPLUGIN_ARG="--auth-plugin ${OPTARG}"; shift ;;
|
||||
--auth-source) AUTHSOURCE_ARG="--auth-source ${OPTARG}"; shift ;;
|
||||
-h|--help) usage ;;
|
||||
-*) usage "Unknown chrooter option: ${param}" ;;
|
||||
*) break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$LISTEN" != "$PORT" ]; then
|
||||
HOST=${LISTEN%:*}
|
||||
PORT=${LISTEN##*:}
|
||||
# if no host was given, restore
|
||||
[ "$HOST" = "$PORT" ] && HOST=""
|
||||
fi
|
||||
|
||||
# Sanity checks
|
||||
if [ -z "${HOST}" ]; then
|
||||
if bash -c "exec 7<>/dev/tcp/localhost/${PORT}" &> /dev/null; then
|
||||
exec 7<&-
|
||||
exec 7>&-
|
||||
die "Port ${PORT} in use. Try --listen PORT"
|
||||
else
|
||||
exec 7<&-
|
||||
exec 7>&-
|
||||
fi
|
||||
fi
|
||||
|
||||
trap "cleanup" TERM QUIT INT EXIT
|
||||
|
||||
# Find vnc.html
|
||||
if [ -n "${WEB}" ]; then
|
||||
if [ ! -e "${WEB}/vnc.html" ]; then
|
||||
die "Could not find ${WEB}/vnc.html"
|
||||
fi
|
||||
elif [ -e "$(pwd)/vnc.html" ]; then
|
||||
WEB=$(pwd)
|
||||
elif [ -e "${HERE}/../vnc.html" ]; then
|
||||
WEB=${HERE}/../
|
||||
elif [ -e "${HERE}/vnc.html" ]; then
|
||||
WEB=${HERE}
|
||||
elif [ -e "${HERE}/../share/novnc/vnc.html" ]; then
|
||||
WEB=${HERE}/../share/novnc/
|
||||
else
|
||||
die "Could not find vnc.html"
|
||||
fi
|
||||
|
||||
# Find self.pem
|
||||
if [ -n "${CERT}" ]; then
|
||||
if [ ! -e "${CERT}" ]; then
|
||||
die "Could not find ${CERT}"
|
||||
fi
|
||||
elif [ -e "$(pwd)/self.pem" ]; then
|
||||
CERT="$(pwd)/self.pem"
|
||||
elif [ -e "${HERE}/../self.pem" ]; then
|
||||
CERT="${HERE}/../self.pem"
|
||||
elif [ -e "${HERE}/self.pem" ]; then
|
||||
CERT="${HERE}/self.pem"
|
||||
else
|
||||
echo "Warning: could not find self.pem"
|
||||
fi
|
||||
|
||||
# Check key file
|
||||
if [ -n "${KEY}" ]; then
|
||||
if [ ! -e "${KEY}" ]; then
|
||||
die "Could not find ${KEY}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# try to find websockify (prefer local, try global, then download local)
|
||||
if [[ -d ${HERE}/websockify ]]; then
|
||||
WEBSOCKIFY=${HERE}/websockify/run
|
||||
|
||||
if [[ ! -x $WEBSOCKIFY ]]; then
|
||||
echo "The path ${HERE}/websockify exists, but $WEBSOCKIFY either does not exist or is not executable."
|
||||
echo "If you intended to use an installed websockify package, please remove ${HERE}/websockify."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Using local websockify at $WEBSOCKIFY"
|
||||
else
|
||||
WEBSOCKIFY_FROMSYSTEM=$(which websockify 2>/dev/null)
|
||||
WEBSOCKIFY_FROMSNAP=${HERE}/../usr/bin/python2-websockify
|
||||
[ -f $WEBSOCKIFY_FROMSYSTEM ] && WEBSOCKIFY=$WEBSOCKIFY_FROMSYSTEM
|
||||
[ -f $WEBSOCKIFY_FROMSNAP ] && WEBSOCKIFY=$WEBSOCKIFY_FROMSNAP
|
||||
|
||||
if [ ! -f "$WEBSOCKIFY" ]; then
|
||||
echo "No installed websockify, attempting to clone websockify..."
|
||||
WEBSOCKIFY=${HERE}/websockify/run
|
||||
git clone https://github.com/novnc/websockify ${HERE}/websockify
|
||||
|
||||
if [[ ! -e $WEBSOCKIFY ]]; then
|
||||
echo "Unable to locate ${HERE}/websockify/run after downloading"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Using local websockify at $WEBSOCKIFY"
|
||||
else
|
||||
echo "Using installed websockify at $WEBSOCKIFY"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Make all file paths absolute as websockify changes working directory
|
||||
WEB=`realpath "${WEB}"`
|
||||
[ -n "${CERT}" ] && CERT=`realpath "${CERT}"`
|
||||
[ -n "${KEY}" ] && KEY=`realpath "${KEY}"`
|
||||
[ -n "${RECORD}" ] && RECORD=`realpath "${RECORD}"`
|
||||
|
||||
echo "Starting webserver and WebSockets proxy on${HOST:+ host ${HOST}} port ${PORT}"
|
||||
${WEBSOCKIFY} ${SYSLOG_ARG} ${SSLONLY} ${FILEONLY_ARG} --web ${WEB} ${CERT:+--cert ${CERT}} ${KEY:+--key ${KEY}} ${LISTEN} ${VNC_DEST} ${HEARTBEAT_ARG} ${IDLETIMEOUT_ARG} ${RECORD:+--record ${RECORD}} ${TIMEOUT_ARG} ${WEBAUTH_ARG} ${AUTHPLUGIN_ARG} ${AUTHSOURCE_ARG} &
|
||||
proxy_pid="$!"
|
||||
sleep 1
|
||||
if [ -z "$proxy_pid" ] || ! ps -eo pid= | grep -w "$proxy_pid" > /dev/null; then
|
||||
proxy_pid=
|
||||
echo "Failed to start WebSockets proxy"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$HOST" ]; then
|
||||
HOST=$(hostname)
|
||||
fi
|
||||
|
||||
echo -e "\n\nNavigate to this URL:\n"
|
||||
if [ "x$SSLONLY" == "x" ]; then
|
||||
echo -e " http://${HOST}:${PORT}/vnc.html?host=${HOST}&port=${PORT}\n"
|
||||
else
|
||||
echo -e " https://${HOST}:${PORT}/vnc.html?host=${HOST}&port=${PORT}\n"
|
||||
fi
|
||||
|
||||
echo -e "Press Ctrl-C to exit\n\n"
|
||||
|
||||
wait ${proxy_pid}
|
||||
28
VM/novnc/utils/u2x11
Executable file
28
VM/novnc/utils/u2x11
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Convert "U+..." commented entries in /usr/include/X11/keysymdef.h
|
||||
# into JavaScript for use by noVNC. Note this is likely to produce
|
||||
# a few duplicate properties with clashing values, that will need
|
||||
# resolving manually.
|
||||
#
|
||||
# Colin Dean <colin@xvpsource.org>
|
||||
#
|
||||
|
||||
regex="^#define[ \t]+XK_[A-Za-z0-9_]+[ \t]+0x([0-9a-fA-F]+)[ \t]+\/\*[ \t]+U\+([0-9a-fA-F]+)[ \t]+[^*]+.[ \t]+\*\/[ \t]*$"
|
||||
echo "unicodeTable = {"
|
||||
while read line; do
|
||||
if echo "${line}" | egrep -qs "${regex}"; then
|
||||
|
||||
x11=$(echo "${line}" | sed -r "s/${regex}/\1/")
|
||||
vnc=$(echo "${line}" | sed -r "s/${regex}/\2/")
|
||||
|
||||
if echo "${vnc}" | egrep -qs "^00[2-9A-F][0-9A-F]$"; then
|
||||
: # skip ISO Latin-1 (U+0020 to U+00FF) as 1-to-1 mapping
|
||||
else
|
||||
# note 1-to-1 is possible (e.g. for Euro symbol, U+20AC)
|
||||
echo " 0x${vnc} : 0x${x11},"
|
||||
fi
|
||||
fi
|
||||
done < /usr/include/X11/keysymdef.h | uniq
|
||||
echo "};"
|
||||
|
||||
45
VM/novnc/utils/validate
Executable file
45
VM/novnc/utils/validate
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
RET=0
|
||||
|
||||
OUT=`mktemp`
|
||||
|
||||
for fn in "$@"; do
|
||||
echo "Validating $fn..."
|
||||
echo
|
||||
|
||||
case $fn in
|
||||
*.html)
|
||||
type="text/html"
|
||||
;;
|
||||
*.css)
|
||||
type="text/css"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown format!"
|
||||
echo
|
||||
RET=1
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
curl --silent \
|
||||
--header "Content-Type: ${type}; charset=utf-8" \
|
||||
--data-binary @${fn} \
|
||||
https://validator.w3.org/nu/?out=text > $OUT
|
||||
cat $OUT
|
||||
echo
|
||||
|
||||
# We don't fail the check for warnings as some warnings are
|
||||
# not relevant for us, and we don't currently have a way to
|
||||
# ignore just those
|
||||
if grep -q -s -E "^Error:" $OUT; then
|
||||
RET=1
|
||||
fi
|
||||
done
|
||||
|
||||
rm $OUT
|
||||
|
||||
exit $RET
|
||||
Reference in New Issue
Block a user