cloudstack/systemvm/agent/noVNC/keymaps/generate-language-keymaps.py
Wei Zhou a1af03f413
noVNC: fix JP keyboard on vmware7+ which uses websocket URL (#7694)
* noVNC: fix JP keyboard on vmware7+ which uses websocket URL

* noVNC: cleanup rfb.js

* noVNC: fix < and > on JP keyboard

* noVNC: fix Caps lock on JP keyboard
2023-08-09 11:43:16 +02:00

128 lines
4.3 KiB
Python
Executable File

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