Hash :
d1cb8ad4
Author :
Date :
2018-08-14T11:16:30
test: add a tool to test-compile all LVO combinations from xkeyboard-config This test contains of two parts: - a simple program to convert RMLVO commandline arguments into a keymap (and print that keymap if requested). - a python script that runs through rules/evdev.xml, and tries to compile a keymap for sort-of every layout/variant/option combination. Sort-of, because we can have multiple options and it really only does one per layout(variant) combination. Same thing can be done using xkbcomp, but right now it doesn't take that as argument, it's hard-coded. This takes quite a while, installing python-tqdm is recommended to see fancy progress bars instead of just miles of dumps. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
#!/usr/bin/env python
import sys
import subprocess
import os
import xml.etree.ElementTree as ET
verbose = True
DEFAULT_RULES_XML = '@XKB_CONFIG_ROOT@/rules/evdev.xml'
# Meson needs to fill this in so we can call the tool in the buildir.
EXTRA_PATH='@MESON_BUILD_ROOT@'
os.environ['PATH'] = ':'.join([EXTRA_PATH, os.getenv('PATH')])
# The function generating the progress bar (if any).
progress_bar = lambda x, desc: x
if os.isatty(sys.stdout.fileno()):
try:
from tqdm import tqdm
progress_bar = tqdm
verbose = False
except ImportError:
pass
def xkbcommontool(r='evdev', m='pc105', l='us', v=None, o=None):
args = [
'rmlvo-to-keymap',
'--rules', r,
'--model', m,
'--layout', l,
]
if v is not None:
args += ['--variant', v]
if o is not None:
args += ['--options', o]
if verbose:
print(':: {}'.format(' '.join(args)))
try:
output = subprocess.check_output(args, stderr=subprocess.STDOUT)
if verbose:
print(output.decode('utf-8'))
except subprocess.CalledProcessError as err:
print('ERROR: Failed to compile: {}'.format(' '.join(args)))
print(err.output.decode('utf-8'))
sys.exit(1)
def xkbcomp(r='evdev', m='pc105', l='us', v='', o=''):
args = ['setxkbmap', '-print']
if r is not None:
args.append('-rules')
args.append('{}'.format(r))
if m is not None:
args.append('-model')
args.append('{}'.format(m))
if l is not None:
args.append('-layout')
args.append('{}'.format(l))
if o is not None:
args.append('-option')
args.append('{}'.format(o))
if verbose:
print(':: {}'.format(' '.join(args)))
try:
xkbcomp_args = ['xkbcomp', '-xkb', '-', '-']
setxkbmap = subprocess.Popen(args, stdout=subprocess.PIPE)
xkbcomp = subprocess.Popen(xkbcomp_args, stdin=setxkbmap.stdout,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
setxkbmap.stdout.close()
stdout, stderr = xkbcomp.communicate()
if xkbcomp.returncode != 0:
print('ERROR: Failed to compile: {}'.format(' '.join(args)))
if xkbcomp.returncode != 0 or verbose:
print(stdout.decode('utf-8'))
print(stderr.decode('utf-8'))
# This catches setxkbmap errors.
except subprocess.CalledProcessError as err:
print('ERROR: Failed to compile: {}'.format(' '.join(args)))
print(err.output.decode('utf-8'))
def parse(root):
layouts = root.findall('layoutList/layout')
options = [
e.text
for e in root.findall('optionList/group/option/configItem/name')
]
# Switch this to xkbcomp if needed.
tool = xkbcommontool
# tool = xkbcomp
for l in progress_bar(layouts, 'layout '):
layout = l.find('configItem/name').text
tool(l=layout)
variants = l.findall('variantList/variant')
for v in progress_bar(variants, 'variant'):
variant = v.find('configItem/name').text
tool(l=layout, v=variant)
for option in progress_bar(options, 'option '):
tool(l=layout, v=variant, o=option)
def main(args):
try:
path = args[1]
except IndexError:
path = DEFAULT_RULES_XML
with open(path) as f:
root = ET.fromstring(f.read())
parse(root)
if __name__ == '__main__':
main(sys.argv)