2013-06-04 09:52:20 +10:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
# Parses linux/input.h scanning for #define KEY_FOO 134
|
2013-10-28 17:16:45 +01:00
|
|
|
# Prints C header files or Python files that can be used as
|
|
|
|
|
# mapping and lookup tables.
|
2013-06-04 09:52:20 +10:00
|
|
|
#
|
|
|
|
|
|
2013-08-26 08:53:46 +10:00
|
|
|
from __future__ import print_function
|
2013-06-04 09:52:20 +10:00
|
|
|
import re
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
class Bits(object):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
prefixes = [
|
|
|
|
|
"EV_",
|
|
|
|
|
"REL_",
|
|
|
|
|
"ABS_",
|
|
|
|
|
"KEY_",
|
|
|
|
|
"BTN_",
|
|
|
|
|
"LED_",
|
|
|
|
|
"SND_",
|
|
|
|
|
"MSC_",
|
|
|
|
|
"SW_",
|
|
|
|
|
"FF_",
|
|
|
|
|
"SYN_",
|
2013-06-05 16:43:15 +10:00
|
|
|
"REP_",
|
2013-06-04 09:52:20 +10:00
|
|
|
"INPUT_PROP_",
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
blacklist = [
|
2013-06-04 11:11:25 +10:00
|
|
|
"EV_VERSION",
|
|
|
|
|
"BTN_MISC",
|
|
|
|
|
"BTN_MOUSE",
|
|
|
|
|
"BTN_JOYSTICK",
|
|
|
|
|
"BTN_GAMEPAD",
|
|
|
|
|
"BTN_DIGI",
|
|
|
|
|
"BTN_WHEEL",
|
|
|
|
|
"BTN_TRIGGER_HAPPY"
|
2013-06-04 09:52:20 +10:00
|
|
|
]
|
|
|
|
|
|
2013-10-28 17:16:45 +01:00
|
|
|
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_",
|
|
|
|
|
]
|
|
|
|
|
|
2013-06-04 09:52:20 +10:00
|
|
|
def print_bits(bits, prefix):
|
|
|
|
|
if not hasattr(bits, prefix):
|
|
|
|
|
return
|
2013-08-26 08:53:46 +10:00
|
|
|
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))
|
2013-10-28 17:16:45 +01:00
|
|
|
if prefix == "key":
|
|
|
|
|
for val, name in list(getattr(bits, "btn").items()):
|
|
|
|
|
print(" [%s] = \"%s\"," % (name, name))
|
2013-08-26 08:53:46 +10:00
|
|
|
print("};")
|
|
|
|
|
print("")
|
2013-06-04 09:52:20 +10:00
|
|
|
|
|
|
|
|
def print_map(bits):
|
2013-08-26 08:53:46 +10:00
|
|
|
print("static const char * const * const event_type_map[EV_MAX + 1] = {")
|
2013-06-04 09:52:20 +10:00
|
|
|
|
|
|
|
|
for prefix in prefixes:
|
|
|
|
|
if prefix == "BTN_" or prefix == "EV_" or prefix == "INPUT_PROP_":
|
|
|
|
|
continue
|
2013-08-26 08:53:46 +10:00
|
|
|
print(" [EV_%s] = %s_map," % (prefix[:-1], prefix[:-1].lower()))
|
2013-06-04 09:52:20 +10:00
|
|
|
|
2013-08-26 08:53:46 +10:00
|
|
|
print("};")
|
|
|
|
|
print("")
|
2013-06-04 09:52:20 +10:00
|
|
|
|
2015-01-06 09:04:18 +10:00
|
|
|
print("#if __clang__")
|
|
|
|
|
print("#pragma clang diagnostic push")
|
|
|
|
|
print("#pragma clang diagnostic ignored \"-Winitializer-overrides\"")
|
|
|
|
|
print("#else")
|
2013-08-22 16:04:40 +10:00
|
|
|
print("#pragma GCC diagnostic push")
|
|
|
|
|
print("#pragma GCC diagnostic ignored \"-Woverride-init\"")
|
2015-01-06 09:04:18 +10:00
|
|
|
print("#endif")
|
2013-08-26 08:53:46 +10:00
|
|
|
print("static const int ev_max[EV_MAX + 1] = {")
|
|
|
|
|
print(" [0 ... EV_MAX] = -1,")
|
2013-06-04 09:52:20 +10:00
|
|
|
for prefix in prefixes:
|
|
|
|
|
if prefix == "BTN_" or prefix == "EV_" or prefix == "INPUT_PROP_":
|
|
|
|
|
continue
|
2013-08-26 08:53:46 +10:00
|
|
|
print(" [EV_%s] = %s_MAX," % (prefix[:-1], prefix[:-1]))
|
|
|
|
|
print("};")
|
2015-01-06 09:04:18 +10:00
|
|
|
print("#if __clang__")
|
|
|
|
|
print("#pragma clang diagnostic pop /* \"-Winitializer-overrides\" */")
|
|
|
|
|
print("#else")
|
2013-08-22 16:04:40 +10:00
|
|
|
print("#pragma GCC diagnostic pop /* \"-Woverride-init\" */")
|
2015-01-06 09:04:18 +10:00
|
|
|
print("#endif");
|
2013-08-26 08:53:46 +10:00
|
|
|
print("")
|
2013-06-04 09:52:20 +10:00
|
|
|
|
2013-10-28 17:16:45 +01:00
|
|
|
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("")
|
2014-08-18 10:33:18 +10:00
|
|
|
print("static const struct name_entry prop_names[] = {")
|
|
|
|
|
print_lookup(bits, "input_prop")
|
|
|
|
|
print("};")
|
|
|
|
|
print("")
|
2013-10-28 17:16:45 +01:00
|
|
|
|
2013-06-04 09:52:20 +10:00
|
|
|
def print_mapping_table(bits):
|
2013-08-26 08:53:46 +10:00
|
|
|
print("/* THIS FILE IS GENERATED, DO NOT EDIT */")
|
|
|
|
|
print("")
|
|
|
|
|
print("#ifndef EVENT_NAMES_H")
|
|
|
|
|
print("#define EVENT_NAMES_H")
|
|
|
|
|
print("")
|
2013-06-04 09:52:20 +10:00
|
|
|
|
|
|
|
|
for prefix in prefixes:
|
|
|
|
|
if prefix == "BTN_":
|
|
|
|
|
continue
|
|
|
|
|
print_bits(bits, prefix[:-1].lower())
|
|
|
|
|
|
|
|
|
|
print_map(bits)
|
2013-10-28 17:16:45 +01:00
|
|
|
print_lookup_table(bits)
|
2013-06-04 09:52:20 +10:00
|
|
|
|
2013-08-26 08:53:46 +10:00
|
|
|
print("#endif /* EVENT_NAMES_H */")
|
2013-06-04 09:52:20 +10:00
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
2013-10-14 15:40:51 +10:00
|
|
|
def parse(fp):
|
2013-06-04 09:52:20 +10:00
|
|
|
bits = Bits()
|
|
|
|
|
|
|
|
|
|
lines = fp.readlines()
|
|
|
|
|
for line in lines:
|
|
|
|
|
if not line.startswith("#define"):
|
|
|
|
|
continue
|
|
|
|
|
parse_define(bits, line)
|
|
|
|
|
|
|
|
|
|
return bits
|
|
|
|
|
|
2014-01-14 14:18:06 +10:00
|
|
|
def usage(prog):
|
2016-03-17 11:02:50 +10:00
|
|
|
print("Usage: cat <files> | %s" % prog)
|
2014-01-14 14:18:06 +10:00
|
|
|
|
2013-06-04 09:52:20 +10:00
|
|
|
if __name__ == "__main__":
|
2016-03-17 11:02:50 +10:00
|
|
|
if len(sys.argv) != 1:
|
2014-01-14 14:18:06 +10:00
|
|
|
usage(sys.argv[0])
|
|
|
|
|
sys.exit(2)
|
|
|
|
|
|
2016-03-17 11:02:50 +10:00
|
|
|
bits = parse(sys.stdin)
|
|
|
|
|
print_mapping_table(bits)
|