#!/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 " % (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:])