| #!/usr/bin/env python |
| |
| # This script |
| # (1) loads keysym name and keycode mappings from noVNC/core/input/keysym.js and |
| # (2) loads keysyn name to atset1 code mappings from keymap files which can be downloadeded from https://github.com/qemu/qemu/blob/master/pc-bios/keymaps |
| # (3) generates the mappings of keycode and atset1 code |
| # |
| # Note: please add language specific mappings if needed. |
| |
| import os |
| import sys |
| |
| keycode_to_x11name = {} |
| x11name_to_atset1 = {} |
| layout = "" |
| result_mappings = {} |
| js_config = [] |
| |
| |
| def generate_x11name_to_atset1_map(keymap_file): |
| # keymap files can be downloadeded from |
| # https://github.com/qemu/qemu/blob/master/pc-bios/keymaps |
| global layout |
| try: |
| for c in open(keymap_file): |
| if len(c.strip()) == 0: |
| continue |
| if c.startswith("# quirks section start"): |
| # Stop at the quirks section |
| break |
| if c.startswith("#"): |
| if "layout" in c and ":" in c: |
| layout = c.split(":")[1].strip() |
| continue |
| if "map " in c: |
| continue |
| values = c.strip().split(" ") |
| if len(values) >= 2: |
| keyname = 'XK_' + values[0] |
| keycode = ' '.join(values[1:]).strip() |
| if keyname not in x11name_to_atset1: |
| x11name_to_atset1[keyname] = keycode |
| else: |
| print("Duplicated atset1 code for x11name '%s': '%s' and '%s'" % ( |
| keyname, x11name_to_atset1[keyname], keycode)) |
| |
| except IOError: |
| print( |
| "File '%s' does not exist. \nkeymaps can be downloaded from https://github.com/qemu/qemu/tree/master/pc-bios/keymaps" % keymap_file) |
| sys.exit(2) |
| |
| |
| def generate_keycode_to_x11name(): |
| for k in open("../core/input/keysym.js"): |
| k = k.strip() |
| if k.startswith("/") or k.startswith("*"): |
| continue |
| values = k.split(":") |
| if len(values) >= 2: |
| keyname = values[0] |
| keycode = values[1].strip().split(",")[0].lower() |
| keycode_int = int(keycode, 16) |
| if str(keycode_int) not in keycode_to_x11name: |
| keycode_to_x11name[str(keycode_int)] = keyname |
| |
| |
| def translate(keysym): |
| x11name = keycode_to_x11name[str(keysym)] |
| if x11name not in x11name_to_atset1: |
| print("Cannot find atset1 code for keysym (%s) / x11name (%s) in keymaps" % (keysym, x11name)) |
| return "", "" |
| atset1 = x11name_to_atset1[x11name] |
| values = atset1.split(" ") |
| rest = "" |
| if len(values) >= 2: |
| atset1 = values[0] |
| rest = " ".join(values[1:]) |
| return str(int(atset1, 16)), rest |
| |
| |
| def add_language_specific_mappings(): |
| if layout == "jp": |
| add_specific_mapping("124", "125", "shift") # bar |
| |
| |
| def add_specific_mapping(keycode, atset1, rest): |
| result_mappings[keycode] = "%s %s" % (str(atset1).ljust(10), rest) |
| |
| |
| def generate_js_file(keymap_file): |
| generated_filename = keymap_file + "-atset1.js" |
| handle = open(generated_filename, "w") |
| js_config.append("/* This file is auto-generated by generate-language-keymaps.py\n") |
| js_config.append(" * command : %s\n" % (" ".join(sys.argv))) |
| js_config.append(" * layout : %s\n" % layout) |
| js_config.append(" */\n") |
| js_config.append("export default {\n") |
| for keycode in dict(sorted(list(result_mappings.items()), key=lambda item: int(item[0]))): |
| js_config.append("%10s : \"%s\",\n" % ("\"" + str(keycode) + "\"", result_mappings[keycode].strip())) |
| js_config.append("}\n") |
| for line in js_config: |
| handle.write(line) |
| handle.close() |
| print("Created file %s" % generated_filename) |
| |
| |
| def main(argv): |
| if len(argv) < 1: |
| print("Usage: %s <keymap file>" % (sys.argv[0])) |
| sys.exit(1) |
| keymap_file = argv[0] |
| generate_keycode_to_x11name() |
| generate_x11name_to_atset1_map(keymap_file) |
| |
| # insert language-specific mappings at beginning |
| add_language_specific_mappings() |
| |
| for keycode in keycode_to_x11name: |
| atset1, rest = translate(keycode) |
| if atset1 and keycode not in result_mappings and int(keycode) < 65000: |
| result_mappings[keycode] = "%s %s" % (str(atset1).ljust(10), rest) |
| |
| generate_js_file(keymap_file) |
| |
| |
| if __name__ == "__main__": |
| main(sys.argv[1:]) |