| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- #!/usr/bin/env python3
- # vim: set expandtab shiftwidth=4:
- # -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
- #
- # Copyright © 2018 Red Hat, Inc.
- #
- # Permission is hereby granted, free of charge, to any person obtaining a
- # copy of this software and associated documentation files (the 'Software'),
- # to deal in the Software without restriction, including without limitation
- # the rights to use, copy, modify, merge, publish, distribute, sublicense,
- # and/or sell copies of the Software, and to permit persons to whom the
- # Software is furnished to do so, subject to the following conditions:
- #
- # The above copyright notice and this permission notice (including the next
- # paragraph) shall be included in all copies or substantial portions of the
- # Software.
- #
- # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- # DEALINGS IN THE SOFTWARE.
- import argparse
- import sys
- try:
- import pyudev
- except ModuleNotFoundError as e:
- print(f"Error: {e!s}", file=sys.stderr)
- print(
- "One or more python modules are missing. Please install those "
- "modules and re-run this tool."
- )
- sys.exit(1)
- def list_devices():
- devices = {}
- context = pyudev.Context()
- for device in context.list_devices(subsystem="input"):
- if (device.device_node or "").startswith("/dev/input/event"):
- parent = device.parent
- if parent is not None:
- name = parent.properties["NAME"] or ""
- # The udev name includes enclosing quotes
- devices[device.device_node] = name[1:-1]
- def versionsort(key):
- return int(key[len("/dev/input/event") :])
- for k in sorted(devices, key=versionsort):
- print(f"{k}:\t{devices[k]}")
- class HidDevice:
- def __init__(self, name, driver, vendor, product, devpath):
- self.name = name
- self.driver = driver
- self.vendor = vendor
- self.product = product
- self.devpath = devpath
- self.hidraws = []
- self.evdevs = []
- def list_hid_devices():
- devices = []
- context = pyudev.Context()
- for device in context.list_devices(subsystem="hid"):
- name = device.properties.get("HID_NAME")
- driver = device.properties.get("DRIVER")
- devpath = device.properties.get("DEVPATH")
- id = device.properties.get("HID_ID") or "0:0:0"
- _, vendor, product = (int(x, 16) for x in id.split(":"))
- devices.append(HidDevice(name, driver, vendor, product, devpath))
- for device in context.list_devices(subsystem="hidraw"):
- devpath = device.properties["DEVPATH"]
- for hid in devices:
- if devpath.startswith(hid.devpath):
- hid.hidraws.append(f"'{device.device_node}'")
- for device in context.list_devices(subsystem="input"):
- if (device.device_node or "").startswith("/dev/input/event"):
- devpath = device.properties["DEVPATH"]
- for hid in devices:
- if devpath.startswith(hid.devpath):
- hid.evdevs.append(f"'{device.device_node}'")
- print("hid:")
- for d in devices:
- print(f"- name: '{d.name}'")
- print(f" id: '{d.vendor:04x}:{d.product:04x}'")
- print(f" driver: '{d.driver}'")
- print(f" hidraw: [{', '.join(h for h in d.hidraws)}]")
- print(f" evdev: [{', '.join(h for h in d.evdevs)}]")
- print()
- def main():
- parser = argparse.ArgumentParser(description="List kernel devices")
- parser.add_argument("--hid", action="store_true", default=False)
- args = parser.parse_args()
- if args.hid:
- list_hid_devices()
- else:
- list_devices()
- if __name__ == "__main__":
- try:
- main()
- except KeyboardInterrupt:
- print("Exited on user request")
|