OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/python |
| 2 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. |
| 5 |
| 6 """Code generator DeviceCapabilities literal.""" |
| 7 |
| 8 import argparse |
| 9 import ctypes |
| 10 import evdev |
| 11 import os |
| 12 import sys |
| 13 |
| 14 |
| 15 TEST_DATA_GROUP_SIZE = 64 # Aligns with sysfs on 64-bit devices. |
| 16 |
| 17 |
| 18 def bits_to_groups(bits): |
| 19 return (bits + TEST_DATA_GROUP_SIZE - 1) / TEST_DATA_GROUP_SIZE |
| 20 |
| 21 |
| 22 # As in /sys/class/input/input*/capabilities/* |
| 23 def serialize_bitfield(bitfield, max_bit): |
| 24 result = "" |
| 25 group_count = bits_to_groups(max_bit) |
| 26 for group in xrange(group_count - 1, -1, -1): |
| 27 group_val = 0 |
| 28 for group_bit in xrange(TEST_DATA_GROUP_SIZE): |
| 29 code = group * TEST_DATA_GROUP_SIZE + group_bit |
| 30 if code in bitfield: |
| 31 group_val |= (1 << group_bit) |
| 32 if group_val or result: |
| 33 result += '%x' % group_val |
| 34 if group: |
| 35 result += ' ' |
| 36 if not result: |
| 37 return '0' |
| 38 return result |
| 39 |
| 40 |
| 41 def dump_absinfo(out, capabilities, identifier): |
| 42 out.write('const DeviceAbsoluteAxis %s[] = {\n' % identifier) |
| 43 |
| 44 for code, absinfo in capabilities[evdev.ecodes.EV_ABS]: |
| 45 # Set value := 0 to make it deterministic. |
| 46 code_name = evdev.ecodes.bytype[evdev.ecodes.EV_ABS][code] |
| 47 absinfo_struct = (0, absinfo.min, absinfo.max, absinfo.fuzz, absinfo.flat, |
| 48 absinfo.resolution) |
| 49 data = (code_name,) + absinfo_struct |
| 50 out.write(' {%s, {%d, %d, %d, %d, %d, %d}},\n' % data) |
| 51 |
| 52 out.write('};\n') |
| 53 |
| 54 |
| 55 def dump_capabilities(out, dev, identifier): |
| 56 capabilities = dev.capabilities() |
| 57 has_abs = evdev.ecodes.EV_ABS in capabilities |
| 58 |
| 59 sysfs_path = '/sys/class/input/' + os.path.basename(dev.fn) |
| 60 |
| 61 # python-evdev is missing some features |
| 62 uniq = open(sysfs_path + '/device/uniq', 'r').read().strip() |
| 63 prop = open(sysfs_path + '/device/properties', 'r').read().strip() |
| 64 ff = open(sysfs_path + '/device/capabilities/ff', 'r').read().strip() |
| 65 |
| 66 # python-evdev parses the id wrong. |
| 67 bustype = open(sysfs_path + '/device/id/bustype', 'r').read().strip() |
| 68 vendor = open(sysfs_path + '/device/id/vendor', 'r').read().strip() |
| 69 product = open(sysfs_path + '/device/id/product', 'r').read().strip() |
| 70 version = open(sysfs_path + '/device/id/version', 'r').read().strip() |
| 71 |
| 72 # python-evdev drops EV_REP from the event set. |
| 73 ev = open(sysfs_path + '/device/capabilities/ev', 'r').read().strip() |
| 74 |
| 75 if ctypes.sizeof(ctypes.c_long()) != 8: |
| 76 # /sys/class/input/*/properties format is word size dependent. |
| 77 # Could be fixed by regrouping but for now, just raise an error. |
| 78 raise ValueError("Must be run on 64-bit machine") |
| 79 |
| 80 key_bits = capabilities.get(evdev.ecodes.EV_KEY, []) |
| 81 rel_bits = capabilities.get(evdev.ecodes.EV_REL, []) |
| 82 abs_bits = [abs[0] for abs in capabilities.get(evdev.ecodes.EV_ABS, [])] |
| 83 msc_bits = capabilities.get(evdev.ecodes.EV_MSC, []) |
| 84 sw_bits = capabilities.get(evdev.ecodes.EV_SW, []) |
| 85 led_bits = capabilities.get(evdev.ecodes.EV_LED, []) |
| 86 |
| 87 fields = [ |
| 88 ('path', os.path.realpath(sysfs_path)), |
| 89 ('name', dev.name), |
| 90 ('phys', dev.phys), |
| 91 ('uniq', uniq), |
| 92 ('bustype', bustype), |
| 93 ('vendor', vendor), |
| 94 ('product', product), |
| 95 ('version', version), |
| 96 ('prop', prop), |
| 97 ('ev', ev), |
| 98 ('key', serialize_bitfield(key_bits, evdev.ecodes.KEY_CNT)), |
| 99 ('rel', serialize_bitfield(rel_bits, evdev.ecodes.REL_CNT)), |
| 100 ('abs', serialize_bitfield(abs_bits, evdev.ecodes.ABS_CNT)), |
| 101 ('msc', serialize_bitfield(msc_bits, evdev.ecodes.MSC_CNT)), |
| 102 ('sw', serialize_bitfield(sw_bits, evdev.ecodes.SW_CNT)), |
| 103 ('led', serialize_bitfield(led_bits, evdev.ecodes.LED_CNT)), |
| 104 ('ff', ff), |
| 105 ] |
| 106 |
| 107 if has_abs: |
| 108 absinfo_identifier = identifier + 'AbsAxes' |
| 109 dump_absinfo(out, capabilities, absinfo_identifier) |
| 110 |
| 111 out.write('const DeviceCapabilities %s = {\n' % identifier) |
| 112 for name, val in fields: |
| 113 out.write(' /* %s */ "%s",\n' % (name, val)) |
| 114 |
| 115 if has_abs: |
| 116 out.write(' %s,\n' % absinfo_identifier) |
| 117 out.write(' arraysize(%s),\n' % absinfo_identifier) |
| 118 |
| 119 out.write('};\n') |
| 120 |
| 121 |
| 122 def main(argv): |
| 123 parser = argparse.ArgumentParser() |
| 124 parser.add_argument('device') |
| 125 parser.add_argument('identifier') |
| 126 args = parser.parse_args(argv) |
| 127 |
| 128 dev = evdev.InputDevice(args.device) |
| 129 out = sys.stdout |
| 130 |
| 131 dump_capabilities(out, dev, args.identifier) |
| 132 return 0 |
| 133 |
| 134 |
| 135 if __name__ == '__main__': |
| 136 sys.exit(main(sys.argv[1:])) |
OLD | NEW |