]>
Commit | Line | Data |
---|---|---|
041568bd PO |
1 | #!/usr/bin/env node |
2 | /* | |
3 | * genkeysymdef: X11 keysymdef.h to JavaScript converter | |
84586c0f | 4 | * Copyright (C) 2018 The noVNC Authors |
041568bd PO |
5 | * Licensed under MPL 2.0 (see LICENSE.txt) |
6 | */ | |
7 | ||
ae52883b | 8 | "use strict"; |
9 | ||
2b5f94fa | 10 | const fs = require('fs'); |
ae52883b | 11 | |
2b5f94fa JD |
12 | let show_help = process.argv.length === 2; |
13 | let filename; | |
ae52883b | 14 | |
2b5f94fa | 15 | for (let i = 2; i < process.argv.length; ++i) { |
7b536961 PO |
16 | switch (process.argv[i]) { |
17 | case "--help": | |
18 | case "-h": | |
19 | show_help = true; | |
20 | break; | |
21 | case "--file": | |
22 | case "-f": | |
23 | default: | |
24 | filename = process.argv[i]; | |
25 | } | |
ae52883b | 26 | } |
27 | ||
28 | if (!filename) { | |
7b536961 PO |
29 | show_help = true; |
30 | console.log("Error: No filename specified\n"); | |
ae52883b | 31 | } |
32 | ||
33 | if (show_help) { | |
7b536961 PO |
34 | console.log("Parses a *nix keysymdef.h to generate Unicode code point mappings"); |
35 | console.log("Usage: node parse.js [options] filename:"); | |
36 | console.log(" -h [ --help ] Produce this help message"); | |
37 | console.log(" filename The keysymdef.h file to parse"); | |
38 | process.exit(0); | |
ae52883b | 39 | } |
40 | ||
2b5f94fa JD |
41 | const buf = fs.readFileSync(filename); |
42 | const str = buf.toString('utf8'); | |
ae52883b | 43 | |
2b5f94fa | 44 | const re = /^#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-fA-F]+)\s*(\/\*\s*(.*)\s*\*\/)?\s*$/m; |
ae52883b | 45 | |
2b5f94fa | 46 | const arr = str.split('\n'); |
ae52883b | 47 | |
2b5f94fa | 48 | const codepoints = {}; |
ae52883b | 49 | |
2b5f94fa JD |
50 | for (let i = 0; i < arr.length; ++i) { |
51 | const result = re.exec(arr[i]); | |
3f1cda2e | 52 | if (result) { |
2b5f94fa JD |
53 | const keyname = result[1]; |
54 | const keysym = parseInt(result[2], 16); | |
55 | const remainder = result[3]; | |
ae52883b | 56 | |
2b5f94fa | 57 | const unicodeRes = /U\+([0-9a-fA-F]+)/.exec(remainder); |
ae52883b | 58 | if (unicodeRes) { |
2b5f94fa | 59 | const unicode = parseInt(unicodeRes[1], 16); |
041568bd | 60 | // The first entry is the preferred one |
3f1cda2e | 61 | if (!codepoints[unicode]) { |
041568bd | 62 | codepoints[unicode] = { keysym: keysym, name: keyname }; |
ae52883b | 63 | } |
64 | } | |
ae52883b | 65 | } |
66 | } | |
67 | ||
2b5f94fa | 68 | let out = |
041568bd PO |
69 | "/*\n" + |
70 | " * Mapping from Unicode codepoints to X11/RFB keysyms\n" + | |
71 | " *\n" + | |
72 | " * This file was automatically generated from keysymdef.h\n" + | |
73 | " * DO NOT EDIT!\n" + | |
74 | " */\n" + | |
524d67f2 | 75 | "\n" + |
041568bd PO |
76 | "/* Functions at the bottom */\n" + |
77 | "\n" + | |
2b5f94fa | 78 | "const codepoints = {\n"; |
041568bd PO |
79 | |
80 | function toHex(num) { | |
2b5f94fa | 81 | let s = num.toString(16); |
041568bd PO |
82 | if (s.length < 4) { |
83 | s = ("0000" + s).slice(-4); | |
84 | } | |
85 | return "0x" + s; | |
8727f598 | 86 | } |
041568bd | 87 | |
2b5f94fa | 88 | for (let codepoint in codepoints) { |
278a5e7f PO |
89 | codepoint = parseInt(codepoint); |
90 | ||
91 | // Latin-1? | |
92 | if ((codepoint >= 0x20) && (codepoint <= 0xff)) { | |
93 | continue; | |
94 | } | |
95 | ||
96 | // Handled by the general Unicode mapping? | |
97 | if ((codepoint | 0x01000000) === codepoints[codepoint].keysym) { | |
98 | continue; | |
99 | } | |
100 | ||
101 | out += " " + toHex(codepoint) + ": " + | |
041568bd PO |
102 | toHex(codepoints[codepoint].keysym) + |
103 | ", // XK_" + codepoints[codepoint].name + "\n"; | |
104 | } | |
105 | ||
106 | out += | |
107 | "};\n" + | |
ae52883b | 108 | "\n" + |
9076defa | 109 | "export default {\n" + |
651c23ec | 110 | " lookup(u) {\n" + |
278a5e7f PO |
111 | " // Latin-1 is one-to-one mapping\n" + |
112 | " if ((u >= 0x20) && (u <= 0xff)) {\n" + | |
113 | " return u;\n" + | |
114 | " }\n" + | |
115 | "\n" + | |
116 | " // Lookup table (fairly random)\n" + | |
2b5f94fa | 117 | " const keysym = codepoints[u];\n" + |
278a5e7f PO |
118 | " if (keysym !== undefined) {\n" + |
119 | " return keysym;\n" + | |
9076defa | 120 | " }\n" + |
278a5e7f PO |
121 | "\n" + |
122 | " // General mapping as final fallback\n" + | |
123 | " return 0x01000000 | u;\n" + | |
9076defa | 124 | " },\n" + |
041568bd | 125 | "};"; |
ae52883b | 126 | |
041568bd | 127 | console.log(out); |