| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- #!/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);
|