5 import xml.etree.ElementTree as ET
10 DEFAULT_RULES_XML = '@XKB_CONFIG_ROOT@/rules/evdev.xml'
12 # Meson needs to fill this in so we can call the tool in the buildir.
13 EXTRA_PATH='@MESON_BUILD_ROOT@'
14 os.environ['PATH'] = ':'.join([EXTRA_PATH, os.getenv('PATH')])
17 # The function generating the progress bar (if any).
18 progress_bar = lambda x, desc: x
19 if os.isatty(sys.stdout.fileno()):
29 def xkbcommontool(r='evdev', m='pc105', l='us', v=None, o=None):
37 args += ['--variant', v]
39 args += ['--options', o]
42 print(':: {}'.format(' '.join(args)))
45 output = subprocess.check_output(args, stderr=subprocess.STDOUT)
47 print(output.decode('utf-8'))
48 except subprocess.CalledProcessError as err:
49 print('ERROR: Failed to compile: {}'.format(' '.join(args)))
50 print(err.output.decode('utf-8'))
54 def xkbcomp(r='evdev', m='pc105', l='us', v='', o=''):
55 args = ['setxkbmap', '-print']
58 args.append('{}'.format(r))
61 args.append('{}'.format(m))
63 args.append('-layout')
64 args.append('{}'.format(l))
66 args.append('-option')
67 args.append('{}'.format(o))
70 print(':: {}'.format(' '.join(args)))
73 xkbcomp_args = ['xkbcomp', '-xkb', '-', '-']
75 setxkbmap = subprocess.Popen(args, stdout=subprocess.PIPE)
76 xkbcomp = subprocess.Popen(xkbcomp_args, stdin=setxkbmap.stdout,
77 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
78 setxkbmap.stdout.close()
79 stdout, stderr = xkbcomp.communicate()
80 if xkbcomp.returncode != 0:
81 print('ERROR: Failed to compile: {}'.format(' '.join(args)))
82 if xkbcomp.returncode != 0 or verbose:
83 print(stdout.decode('utf-8'))
84 print(stderr.decode('utf-8'))
86 # This catches setxkbmap errors.
87 except subprocess.CalledProcessError as err:
88 print('ERROR: Failed to compile: {}'.format(' '.join(args)))
89 print(err.output.decode('utf-8'))
93 layouts = root.findall('layoutList/layout')
97 for e in root.findall('optionList/group/option/configItem/name')
100 # Switch this to xkbcomp if needed.
104 for l in progress_bar(layouts, 'layout '):
105 layout = l.find('configItem/name').text
108 variants = l.findall('variantList/variant')
109 for v in progress_bar(variants, 'variant'):
110 variant = v.find('configItem/name').text
111 tool(l=layout, v=variant)
113 for option in progress_bar(options, 'option '):
114 tool(l=layout, v=variant, o=option)
121 path = DEFAULT_RULES_XML
123 with open(path) as f:
124 root = ET.fromstring(f.read())
128 if __name__ == '__main__':