2 # Copyright 2015 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.
6 """Explain device capabilities from /proc/bus/input/devices.
8 This tool processes the contents of /proc/bus/input/devices, expanding bitfields
9 of event codes into lists of names for those events.
17 def parse_bitfield(bitfield
, word_bits
):
18 """Parse a serialized bitfield from /proc/bus/input/devices.
20 Returns a list of bits in the set.
22 Example: parse_bitfield('10 3', 64) == [0, 1, 68]
24 groups
= bitfield
.split(' ')
25 group_count
= len(groups
)
28 for group_index
in xrange(group_count
):
29 group_val
= int(groups
[group_count
- 1 - group_index
], 16)
31 for group_bit
in xrange(word_bits
):
32 if group_val
& (1 << group_bit
):
33 result_bits
.append(group_index
* word_bits
+ group_bit
)
39 0x0: 'INPUT_PROP_POINTER',
40 0x1: 'INPUT_PROP_DIRECT',
41 0x2: 'INPUT_PROP_BUTTONPAD',
42 0x3: 'INPUT_PROP_SEMI_MT',
43 0x4: 'INPUT_PROP_TOPBUTTONPAD',
47 KEY_NAMES
= evdev
.ecodes
.bytype
[evdev
.ecodes
.EV_KEY
].copy()
49 # Fix keys with multiple names.
50 KEY_NAMES
[evdev
.ecodes
.KEY_MUTE
] = 'KEY_MUTE'
51 KEY_NAMES
[evdev
.ecodes
.KEY_SCREENLOCK
] = 'KEY_SCREENLOCK'
52 KEY_NAMES
[evdev
.ecodes
.KEY_HANGEUL
] = 'KEY_HANGEUL'
53 KEY_NAMES
[evdev
.ecodes
.BTN_LEFT
] = 'BTN_LEFT'
54 KEY_NAMES
[evdev
.ecodes
.BTN_TRIGGER
] = 'BTN_TRIGGER'
55 KEY_NAMES
[evdev
.ecodes
.BTN_0
] = 'BTN_0'
59 ('B: EV=', evdev
.ecodes
.EV
),
60 ('B: PROP=', PROP_NAMES
),
61 ('B: KEY=', KEY_NAMES
),
62 ('B: REL=', evdev
.ecodes
.bytype
[evdev
.ecodes
.EV_REL
]),
63 ('B: MSC=', evdev
.ecodes
.bytype
[evdev
.ecodes
.EV_MSC
]),
64 ('B: LED=', evdev
.ecodes
.bytype
[evdev
.ecodes
.EV_LED
]),
65 ('B: ABS=', evdev
.ecodes
.bytype
[evdev
.ecodes
.EV_ABS
]),
66 ('B: SW=', evdev
.ecodes
.bytype
[evdev
.ecodes
.EV_SW
]),
67 ('B: REP=', evdev
.ecodes
.bytype
[evdev
.ecodes
.EV_REP
]),
68 ('B: SND=', evdev
.ecodes
.bytype
[evdev
.ecodes
.EV_SND
]),
72 def explain_bitfield(serialized_bits
, bit_names
, word_size
, output_file
):
73 """Annotate a bitfield using the provided symbolic names for each bit."""
75 bits
= parse_bitfield(serialized_bits
, word_size
)
78 output_file
.write(' %s\n' % bit_names
[bit
])
80 output_file
.write(' 0x%x\n' % bit
)
83 def explain(input_file
, output_file
, word_size
):
84 """Annotate an input file formatted like /proc/bus/input/devices."""
86 for line
in input_file
:
87 output_file
.write(line
)
88 for prefix
, bit_names
in BITFIELDS
:
89 if line
.startswith(prefix
):
90 explain_bitfield(line
[len(prefix
):], bit_names
, word_size
, output_file
)
94 parser
= argparse
.ArgumentParser()
95 parser
.add_argument('input_file', nargs
='?',
96 default
='/proc/bus/input/devices',
97 help="filename to read input from")
98 parser
.add_argument('output_file', nargs
='?',
99 help="filename to write output to")
100 parser
.add_argument('--word_size', type=int, default
=64,
101 help="word size of the system that generated the input file")
102 args
= parser
.parse_args(argv
)
104 input_file
= sys
.stdin
106 input_file
= open(args
.input_file
, 'r')
108 output_file
= sys
.stdout
110 output_file
= open(args
.output_file
, 'w')
112 explain(input_file
, output_file
, args
.word_size
)
117 if __name__
== '__main__':
118 sys
.exit(main(sys
.argv
[1:]))