tools: make debug-events accept multiple device nodes
authorPeter Hutterer <peter.hutterer@who-t.net>
Mon, 25 Nov 2019 02:22:19 +0000 (12:22 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Tue, 26 Nov 2019 00:34:08 +0000 (00:34 +0000)
For interaction between devices it's necessary to look at more than one device
at a time.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
tools/libinput-debug-events.c
tools/libinput-debug-events.man
tools/libinput-debug-gui.c
tools/libinput-debug-tablet.c
tools/libinput-list-devices.c
tools/shared.c
tools/shared.h
tools/test-tool-option-parsing.py

index 069ef3c..33b850f 100644 (file)
@@ -38,6 +38,8 @@
 #include <libinput.h>
 #include <libevdev/libevdev.h>
 
+#include "util-strings.h"
+#include "util-macros.h"
 #include "shared.h"
 
 static uint32_t start_time;
@@ -924,7 +926,7 @@ mainloop(struct libinput *li)
 
 static void
 usage(void) {
-       printf("Usage: libinput debug-events [options] [--udev <seat>|--device /dev/input/event0]\n");
+       printf("Usage: libinput debug-events [options] [--udev <seat>|--device /dev/input/event0 ...]\n");
 }
 
 int
@@ -932,7 +934,8 @@ main(int argc, char **argv)
 {
        struct libinput *li;
        enum tools_backend backend = BACKEND_NONE;
-       const char *seat_or_device = "seat0";
+       char *seat_or_devices[64] = {NULL};
+       size_t ndevices = 0;
        bool grab = false;
        bool verbose = false;
        struct sigaction act;
@@ -981,12 +984,25 @@ main(int argc, char **argv)
                        be_quiet = true;
                        break;
                case OPT_DEVICE:
+                       if (backend == BACKEND_UDEV ||
+                           ndevices >= ARRAY_LENGTH(seat_or_devices)) {
+                               usage();
+                               return EXIT_INVALID_USAGE;
+
+                       }
                        backend = BACKEND_DEVICE;
-                       seat_or_device = optarg;
+                       seat_or_devices[ndevices++] = safe_strdup(optarg);
                        break;
                case OPT_UDEV:
+                       if (backend == BACKEND_DEVICE ||
+                           ndevices >= ARRAY_LENGTH(seat_or_devices)) {
+                               usage();
+                               return EXIT_INVALID_USAGE;
+
+                       }
                        backend = BACKEND_UDEV;
-                       seat_or_device = optarg;
+                       seat_or_devices[0] = safe_strdup(optarg);
+                       ndevices = 1;
                        break;
                case OPT_GRAB:
                        grab = true;
@@ -1005,14 +1021,18 @@ main(int argc, char **argv)
        }
 
        if (optind < argc) {
-               if (optind < argc - 1 || backend != BACKEND_NONE) {
+               if (backend == BACKEND_UDEV) {
                        usage();
                        return EXIT_INVALID_USAGE;
                }
                backend = BACKEND_DEVICE;
-               seat_or_device = argv[optind];
+               do {
+                       seat_or_devices[ndevices++] = safe_strdup(argv[optind]);
+               } while(++optind < argc);
        } else if (backend == BACKEND_NONE) {
                backend = BACKEND_UDEV;
+               seat_or_devices[0] = safe_strdup("seat0");
+               ndevices = 1;
        }
 
        memset(&act, 0, sizeof(act));
@@ -1025,10 +1045,13 @@ main(int argc, char **argv)
                return EXIT_FAILURE;
        }
 
-       li = tools_open_backend(backend, seat_or_device, verbose, &grab);
+       li = tools_open_backend(backend, seat_or_devices, verbose, &grab);
        if (!li)
                return EXIT_FAILURE;
 
+       while (ndevices-- > 0)
+               free(seat_or_devices[ndevices]);
+
        mainloop(li);
 
        libinput_unref(li);
index 0fc7300..39fbace 100644 (file)
@@ -6,7 +6,7 @@ libinput\-debug\-events \- debug helper for libinput
 .PP
 .B libinput debug\-events \fI[options]\fB \-\-udev \fI<seat>\fB
 .PP
-.B libinput debug\-events \fI[options]\fB [\-\-device] \fI/dev/input/event0\fB
+.B libinput debug\-events \fI[options]\fB [\-\-device] \fI/dev/input/event0\fB [\fI/dev/input/event1\fB...]
 .SH DESCRIPTION
 .PP
 The
@@ -21,7 +21,7 @@ This tool usually needs to be run as root to have access to the
 .SH OPTIONS
 .TP 8
 .B \-\-device \fI/dev/input/event0\fR
-Use the given device with the path backend. The \fB\-\-device\fR argument may be
+Use the given device(s) with the path backend. The \fB\-\-device\fR argument may be
 omitted.
 .TP 8
 .B \-\-grab
index 516d8c4..72fef04 100644 (file)
@@ -1519,7 +1519,7 @@ main(int argc, char **argv)
        struct tools_options options;
        struct libinput *li;
        enum tools_backend backend = BACKEND_NONE;
-       const char *seat_or_device = "seat0";
+       char *seat_or_device[2] = {"seat0", NULL};
        bool verbose = false;
 
        if (!gtk_init_check(&argc, &argv))
@@ -1562,11 +1562,11 @@ main(int argc, char **argv)
                        break;
                case OPT_DEVICE:
                        backend = BACKEND_DEVICE;
-                       seat_or_device = optarg;
+                       seat_or_device[0] = optarg;
                        break;
                case OPT_UDEV:
                        backend = BACKEND_UDEV;
-                       seat_or_device = optarg;
+                       seat_or_device[0] = optarg;
                        break;
                case OPT_GRAB:
                        w.grab = true;
@@ -1590,7 +1590,7 @@ main(int argc, char **argv)
                        return EXIT_INVALID_USAGE;
                }
                backend = BACKEND_DEVICE;
-               seat_or_device = argv[optind];
+               seat_or_device[0] = argv[optind];
        } else if (backend == BACKEND_NONE) {
                backend = BACKEND_UDEV;
        }
index cab2928..b2406d6 100644 (file)
@@ -511,7 +511,7 @@ main(int argc, char **argv)
        struct context ctx;
        struct libinput *li;
        enum tools_backend backend = BACKEND_NONE;
-       const char *seat_or_device = "seat0";
+       char *seat_or_device[2] = {"seat0", NULL};
        struct sigaction act;
        bool grab = false;
 
@@ -548,11 +548,11 @@ main(int argc, char **argv)
                        break;
                case OPT_DEVICE:
                        backend = BACKEND_DEVICE;
-                       seat_or_device = optarg;
+                       seat_or_device[0] = optarg;
                        break;
                case OPT_UDEV:
                        backend = BACKEND_UDEV;
-                       seat_or_device = optarg;
+                       seat_or_device[0] = optarg;
                        break;
                }
 
@@ -564,7 +564,7 @@ main(int argc, char **argv)
                        return EXIT_INVALID_USAGE;
                }
                backend = BACKEND_DEVICE;
-               seat_or_device = argv[optind];
+               seat_or_device[0] = argv[optind];
        } else if (backend == BACKEND_NONE) {
                backend = BACKEND_UDEV;
        }
index 29f80ce..4e0e2c8 100644 (file)
@@ -376,6 +376,7 @@ main(int argc, char **argv)
        struct libinput *li;
        struct libinput_event *ev;
        bool grab = false;
+       char *seat[2] = {"seat0", NULL};
 
        /* This is kept for backwards-compatibility with the old
           libinput-list-devices */
@@ -392,7 +393,7 @@ main(int argc, char **argv)
                }
        }
 
-       li = tools_open_backend(BACKEND_UDEV, "seat0", false, &grab);
+       li = tools_open_backend(BACKEND_UDEV, seat, false, &grab);
        if (!li)
                return 1;
 
index 7dba96d..05a35d0 100644 (file)
@@ -305,14 +305,15 @@ out:
 }
 
 static struct libinput *
-tools_open_device(const char *path, bool verbose, bool *grab)
+tools_open_device(char **paths, bool verbose, bool *grab)
 {
        struct libinput_device *device;
        struct libinput *li;
+       char **p = paths;
 
        li = libinput_path_create_context(&interface, grab);
        if (!li) {
-               fprintf(stderr, "Failed to initialize context from %s\n", path);
+               fprintf(stderr, "Failed to initialize path context\n");
                return NULL;
        }
 
@@ -321,11 +322,15 @@ tools_open_device(const char *path, bool verbose, bool *grab)
                libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG);
        }
 
-       device = libinput_path_add_device(li, path);
-       if (!device) {
-               fprintf(stderr, "Failed to initialize device %s\n", path);
-               libinput_unref(li);
-               li = NULL;
+       while (*p) {
+               device = libinput_path_add_device(li, *p);
+               if (!device) {
+                       fprintf(stderr, "Failed to initialize device %s\n", *p);
+                       libinput_unref(li);
+                       li = NULL;
+                       break;
+               }
+               p++;
        }
 
        return li;
@@ -343,7 +348,7 @@ tools_setenv_quirks_dir(void)
 
 struct libinput *
 tools_open_backend(enum tools_backend which,
-                  const char *seat_or_device,
+                  char **seat_or_device,
                   bool verbose,
                   bool *grab)
 {
@@ -353,7 +358,7 @@ tools_open_backend(enum tools_backend which,
 
        switch (which) {
        case BACKEND_UDEV:
-               li = tools_open_udev(seat_or_device, verbose, grab);
+               li = tools_open_udev(seat_or_device[0], verbose, grab);
                break;
        case BACKEND_DEVICE:
                li = tools_open_device(seat_or_device, verbose, grab);
index e36bfd6..18662f6 100644 (file)
@@ -116,7 +116,7 @@ int tools_parse_option(int option,
                       const char *optarg,
                       struct tools_options *options);
 struct libinput* tools_open_backend(enum tools_backend which,
-                                   const char *seat_or_device,
+                                   char **seat_or_devices,
                                    bool verbose,
                                    bool *grab);
 void tools_device_apply_config(struct libinput_device *device,
index 7ac89db..258c484 100755 (executable)
@@ -205,6 +205,12 @@ class TestDebugEvents(TestToolWithOptions, TestLibinputTool):
         self.run_command_unrecognized_option(['--foo'])
         self.run_command_unrecognized_option(['--version'])
 
+    def test_multiple_devices(self):
+        self.run_command_success(['--device', '/dev/input/event0', '/dev/input/event1'])
+        # same event path multiple times? meh, your problem
+        self.run_command_success(['--device', '/dev/input/event0', '/dev/input/event0'])
+        self.run_command_success(['/dev/input/event0', '/dev/input/event1'])
+
 
 class TestDebugGUI(TestToolWithOptions, TestLibinputTool):
     subtool = 'debug-gui'