| #!/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(result_mappings.items(), key=lambda item: int(item[0]))): | 
 |         js_config.append("%10s : \"%s\",\n" % ("\"" + str(keycode) + "\"", result_mappings[keycode].strip())) | 
 |     js_config.append("}") | 
 |     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:]) |