libevdev/libevdev/make-event-names.py
Peter Hutterer 5ea0a27ba6 Add parsing linux/input-event-codes.h, update to kernel v4.5
The kernel has split most of the event codes out to a new header but the FF_
bits are missing from that header. Until this is fixed upstream, change the
event code parsing so it can take two files (using cat and stdin) so we can
update the kernel headers again.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2016-03-30 15:45:58 +10:00

213 lines
4.4 KiB
Python
Executable file

#!/usr/bin/env python
# Parses linux/input.h scanning for #define KEY_FOO 134
# Prints C header files or Python files that can be used as
# mapping and lookup tables.
#
from __future__ import print_function
import re
import sys
class Bits(object):
pass
prefixes = [
"EV_",
"REL_",
"ABS_",
"KEY_",
"BTN_",
"LED_",
"SND_",
"MSC_",
"SW_",
"FF_",
"SYN_",
"REP_",
"INPUT_PROP_",
]
blacklist = [
"EV_VERSION",
"BTN_MISC",
"BTN_MOUSE",
"BTN_JOYSTICK",
"BTN_GAMEPAD",
"BTN_DIGI",
"BTN_WHEEL",
"BTN_TRIGGER_HAPPY"
]
btn_additional = [
[0, "BTN_A"],
[0, "BTN_B"],
[0, "BTN_X"],
[0, "BTN_Y"],
]
names = [
"REL_",
"ABS_",
"KEY_",
"BTN_",
"LED_",
"SND_",
"MSC_",
"SW_",
"FF_",
"SYN_",
"REP_",
]
def print_bits(bits, prefix):
if not hasattr(bits, prefix):
return
print("static const char * const %s_map[%s_MAX + 1] = {" % (prefix, prefix.upper()))
for val, name in list(getattr(bits, prefix).items()):
print(" [%s] = \"%s\"," % (name, name))
if prefix == "key":
for val, name in list(getattr(bits, "btn").items()):
print(" [%s] = \"%s\"," % (name, name))
print("};")
print("")
def print_map(bits):
print("static const char * const * const event_type_map[EV_MAX + 1] = {")
for prefix in prefixes:
if prefix == "BTN_" or prefix == "EV_" or prefix == "INPUT_PROP_":
continue
print(" [EV_%s] = %s_map," % (prefix[:-1], prefix[:-1].lower()))
print("};")
print("")
print("#if __clang__")
print("#pragma clang diagnostic push")
print("#pragma clang diagnostic ignored \"-Winitializer-overrides\"")
print("#else")
print("#pragma GCC diagnostic push")
print("#pragma GCC diagnostic ignored \"-Woverride-init\"")
print("#endif")
print("static const int ev_max[EV_MAX + 1] = {")
print(" [0 ... EV_MAX] = -1,")
for prefix in prefixes:
if prefix == "BTN_" or prefix == "EV_" or prefix == "INPUT_PROP_":
continue
print(" [EV_%s] = %s_MAX," % (prefix[:-1], prefix[:-1]))
print("};")
print("#if __clang__")
print("#pragma clang diagnostic pop /* \"-Winitializer-overrides\" */")
print("#else")
print("#pragma GCC diagnostic pop /* \"-Woverride-init\" */")
print("#endif");
print("")
def print_python_map(bits):
print("map = {")
for val, name in list(getattr(bits, "ev").items()):
name = name[3:]
if name == "REP" or name == "PWR" or name == "FF_STATUS" or name == "MAX":
continue
print(" %d : %s_map," % (val, name.lower()))
print("}")
print("")
def print_lookup(bits, prefix):
if not hasattr(bits, prefix):
return
names = list(getattr(bits, prefix).items())
if prefix == "btn":
names = names + btn_additional;
for val, name in sorted(names, key=lambda e: e[1]):
print(" { .name = \"%s\", .value = %s }," % (name, name))
def print_lookup_table(bits):
print("struct name_entry {")
print(" const char *name;")
print(" unsigned int value;")
print("};")
print("")
print("static const struct name_entry ev_names[] = {")
print_lookup(bits, "ev")
print("};")
print("")
print("static const struct name_entry code_names[] = {")
for prefix in sorted(names, key=lambda e: e):
print_lookup(bits, prefix[:-1].lower())
print("};")
print("")
print("static const struct name_entry prop_names[] = {")
print_lookup(bits, "input_prop")
print("};")
print("")
def print_mapping_table(bits):
print("/* THIS FILE IS GENERATED, DO NOT EDIT */")
print("")
print("#ifndef EVENT_NAMES_H")
print("#define EVENT_NAMES_H")
print("")
for prefix in prefixes:
if prefix == "BTN_":
continue
print_bits(bits, prefix[:-1].lower())
print_map(bits)
print_lookup_table(bits)
print("#endif /* EVENT_NAMES_H */")
def parse_define(bits, line):
m = re.match(r"^#define\s+(\w+)\s+(\w+)", line)
if m == None:
return
name = m.group(1)
if name in blacklist:
return
try:
value = int(m.group(2), 0)
except ValueError:
return
for prefix in prefixes:
if not name.startswith(prefix):
continue
attrname = prefix[:-1].lower()
if not hasattr(bits, attrname):
setattr(bits, attrname, {})
b = getattr(bits, attrname)
b[value] = name
def parse(fp):
bits = Bits()
lines = fp.readlines()
for line in lines:
if not line.startswith("#define"):
continue
parse_define(bits, line)
return bits
def usage(prog):
print("Usage: cat <files> | %s" % prog)
if __name__ == "__main__":
if len(sys.argv) != 1:
usage(sys.argv[0])
sys.exit(2)
bits = parse(sys.stdin)
print_mapping_table(bits)