tools: libinput-record: record the hid report descriptor where available
authorPeter Hutterer <peter.hutterer@who-t.net>
Thu, 20 Dec 2018 04:48:52 +0000 (14:48 +1000)
committerBenjamin Tissoires <benjamin.tissoires@gmail.com>
Wed, 2 Jan 2019 15:24:04 +0000 (15:24 +0000)
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
tools/libinput-record-verify-yaml.py
tools/libinput-record.c
tools/libinput-record.man

index 8e8b9db..30ed190 100755 (executable)
@@ -140,6 +140,15 @@ class TestYaml(unittest.TestCase):
             properties = evdev['properties']
             self.assertTrue(isinstance(properties, list))
 
+    def test_hid(self):
+        devices = self.yaml['devices']
+        for d in devices:
+            hid = d['hid']
+            self.assertTrue(isinstance(hid, list))
+            for byte in hid:
+                self.assertGreaterEqual(byte, 0)
+                self.assertLessEqual(byte, 255)
+
     def test_udev_sections_exist(self):
         sections = ['properties']
         devices = self.yaml['devices']
index 3f4bb7f..e52d20d 100644 (file)
@@ -1615,6 +1615,52 @@ print_evdev_description(struct record_context *ctx, struct record_device *dev)
 }
 
 static inline void
+print_hid_report_descriptor(struct record_context *ctx,
+                           struct record_device *dev)
+{
+       const char *prefix = "/dev/input/event";
+       const char *node;
+       char syspath[PATH_MAX];
+       unsigned char buf[1024];
+       int len;
+       int fd;
+       bool first = true;
+
+       /* we take the shortcut rather than the proper udev approach, the
+          report_descriptor is available in sysfs and two devices up from
+          our device. 2 digits for the event number should be enough.
+          This approach won't work for /dev/input/by-id devices. */
+       if (!strneq(dev->devnode, prefix, strlen(prefix)) ||
+           strlen(dev->devnode) > strlen(prefix) + 2)
+               return;
+
+       node = &dev->devnode[strlen(prefix)];
+       len = snprintf(syspath,
+                      sizeof(syspath),
+                      "/sys/class/input/event%s/device/device/report_descriptor",
+                      node);
+       if (len < 55 || len > 56)
+               return;
+
+       fd = open(syspath, O_RDONLY);
+       if (fd == -1)
+               return;
+
+       iprintf(ctx, "hid: [");
+
+       while ((len = read(fd, buf, sizeof(buf))) > 0) {
+               for (int i = 0; i < len; i++) {
+                       /* YAML requires decimal */
+                       noiprintf(ctx, "%s%u",first ? "" : ", ", buf[i]);
+                       first = false;
+               }
+       }
+       noiprintf(ctx, " ]\n");
+
+       close(fd);
+}
+
+static inline void
 print_udev_properties(struct record_context *ctx, struct record_device *dev)
 {
        struct udev *udev = NULL;
@@ -1778,6 +1824,7 @@ print_device_description(struct record_context *ctx, struct record_device *dev)
        iprintf(ctx, "- node: %s\n", dev->devnode);
 
        print_evdev_description(ctx, dev);
+       print_hid_report_descriptor(ctx, dev);
        print_udev_properties(ctx, dev);
        print_device_quirks(ctx, dev);
        print_libinput_description(ctx, dev);
index 15f5a06..eb22fce 100644 (file)
@@ -145,6 +145,7 @@ devices:
         57: [0, 65535, 0, 0, 0]
         58: [0, 255, 0, 0, 0]
       properties: [0, 2, 4]
+    hid: [12, 23, 34, 45, ...]
     udev:
       properties:
       - ID_INPUT_MOUSE=1
@@ -225,6 +226,9 @@ the device node recorded
 .B evdev
 A dictionary with the evdev device information.
 .TP 8
+.B hid
+A list of integers representing the HID report descriptor bytes.
+.TP 8
 .B udev
 A dictionary with the udev device information.
 .TP 8