Commit ab3be693b39322849b5ecc4aa95827cbb8fe7414

Peter Hutterer 2020-07-13T12:13:23

tools: switch interactive-evdev to getopt_long Requiring long options for this tool means it's immediately obvious what an invocation does, compare e.g. xkbcli interactive-evdev -gcd to the equivalent: xkbcli interactive-evdev --consumed-mode=gtk --enalbe-compose --report-state-changes This drops the evdev offset argument - that offset should never be anything other than 8, having this as argument here is more likely to confuse or produce misleading debugging logs. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

diff --git a/meson.build b/meson.build
index 8de5928..fac5c6b 100644
--- a/meson.build
+++ b/meson.build
@@ -564,15 +564,15 @@ if build_tools
                    install_dir: dir_libexec)
         man_pages += 'tools/xkbcli-how-to-type.1.ronn'
         configh_data.set10('HAVE_XKBCLI_HOW_TO_TYPE', true)
-    endif
-    if cc.has_header('linux/input.h')
-        executable('xkbcli-interactive-evdev',
-                   'tools/interactive-evdev.c',
-                   dependencies: tools_dep,
-                   install: true,
-                   install_dir: dir_libexec)
-        configh_data.set10('HAVE_XKBCLI_INTERACTIVE_EVDEV', true)
-        man_pages += 'tools/xkbcli-interactive-evdev.1.ronn'
+        if cc.has_header('linux/input.h')
+            executable('xkbcli-interactive-evdev',
+                       'tools/interactive-evdev.c',
+                       dependencies: tools_dep,
+                       install: true,
+                       install_dir: dir_libexec)
+            configh_data.set10('HAVE_XKBCLI_INTERACTIVE_EVDEV', true)
+            man_pages += 'tools/xkbcli-interactive-evdev.1.ronn'
+        endif
     endif
     if get_option('enable-x11')
         x11_tools_dep = declare_dependency(
diff --git a/tools/interactive-evdev.c b/tools/interactive-evdev.c
index a49b932..0868b4f 100644
--- a/tools/interactive-evdev.c
+++ b/tools/interactive-evdev.c
@@ -28,6 +28,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <fnmatch.h>
+#include <getopt.h>
 #include <limits.h>
 #include <locale.h>
 #include <signal.h>
@@ -368,11 +369,24 @@ sigintr_handler(int signum)
     terminate = true;
 }
 
+static void
+usage(FILE *fp, char *progname)
+{
+        fprintf(fp, "Usage: %s [--rules <rules>] [--model <model>] "
+                "[--layout <layout>] [--variant <variant>] [--options <options>]\n",
+                progname);
+        fprintf(fp, "      or: %s --keymap <path to keymap file>\n",
+                progname);
+        fprintf(fp, "For both:\n"
+                        "          --report-state-changes (report changes to the state)\n"
+                        "          --enable-compose (enable compose)\n"
+                        "          --consumed-mode={gtk|xkb} (select the consumed mode)\n");
+}
+
 int
 main(int argc, char *argv[])
 {
     int ret = EXIT_FAILURE;
-    int opt;
     struct keyboard *kbds;
     struct xkb_context *ctx = NULL;
     struct xkb_keymap *keymap = NULL;
@@ -385,57 +399,82 @@ main(int argc, char *argv[])
     const char *keymap_path = NULL;
     const char *locale;
     struct sigaction act;
+    enum options {
+        OPT_RULES,
+        OPT_MODEL,
+        OPT_LAYOUT,
+        OPT_VARIANT,
+        OPT_OPTION,
+        OPT_KEYMAP,
+        OPT_CONSUMED_MODE,
+        OPT_COMPOSE,
+        OPT_REPORT_STATE,
+    };
+    static struct option opts[] = {
+        {"help",                 no_argument,            0, 'h'},
+        {"rules",                required_argument,      0, OPT_RULES},
+        {"model",                required_argument,      0, OPT_MODEL},
+        {"layout",               required_argument,      0, OPT_LAYOUT},
+        {"variant",              required_argument,      0, OPT_VARIANT},
+        {"options",              required_argument,      0, OPT_OPTION},
+        {"keymap",               required_argument,      0, OPT_KEYMAP},
+        {"consumed-mode",        required_argument,      0, OPT_CONSUMED_MODE},
+        {"enable-compose",       no_argument,            0, OPT_COMPOSE},
+        {"report-state-changes", no_argument,            0, OPT_REPORT_STATE},
+        {0, 0, 0, 0},
+    };
 
     setlocale(LC_ALL, "");
 
-    while ((opt = getopt(argc, argv, "r:m:l:v:o:k:n:cdg")) != -1) {
+    while (1) {
+        int opt;
+        int option_index = 0;
+
+        opt = getopt_long(argc, argv, "h", opts, &option_index);
+        if (opt == -1)
+            break;
+
         switch (opt) {
-        case 'r':
+        case OPT_RULES:
             rules = optarg;
             break;
-        case 'm':
+        case OPT_MODEL:
             model = optarg;
             break;
-        case 'l':
+        case OPT_LAYOUT:
             layout = optarg;
             break;
-        case 'v':
+        case OPT_VARIANT:
             variant = optarg;
             break;
-        case 'o':
+        case OPT_OPTION:
             options = optarg;
             break;
-        case 'k':
+        case OPT_KEYMAP:
             keymap_path = optarg;
             break;
-        case 'n':
-            errno = 0;
-            evdev_offset = strtol(optarg, NULL, 10);
-            if (errno) {
-                fprintf(stderr, "error: -n option expects a number\n");
-                exit(EXIT_INVALID_USAGE);
-            }
-            break;
-        case 'c':
+        case OPT_REPORT_STATE:
             report_state_changes = true;
             break;
-        case 'd':
+        case OPT_COMPOSE:
             with_compose = true;
             break;
-        case 'g':
-            consumed_mode = XKB_CONSUMED_MODE_GTK;
+        case OPT_CONSUMED_MODE:
+            if (strcmp(optarg, "gtk") == 0) {
+                consumed_mode = XKB_CONSUMED_MODE_GTK;
+            } else if (strcmp(optarg, "xkb") == 0) {
+                consumed_mode = XKB_CONSUMED_MODE_XKB;
+            } else {
+                usage(stderr, argv[0]);
+                return EXIT_INVALID_USAGE;
+            }
             break;
+        case 'h':
+            usage(stdout, argv[0]);
+            return EXIT_SUCCESS;
         case '?':
-            fprintf(stderr, "   Usage: %s [-r <rules>] [-m <model>] "
-                    "[-l <layout>] [-v <variant>] [-o <options>]\n",
-                    argv[0]);
-            fprintf(stderr, "      or: %s -k <path to keymap file>\n",
-                    argv[0]);
-            fprintf(stderr, "For both: -n <evdev keycode offset>\n"
-                            "          -c (to report changes to the state)\n"
-                            "          -d (to enable compose)\n"
-                            "          -g (to use GTK consumed mode)\n");
-            exit(EXIT_INVALID_USAGE);
+            usage(stderr, argv[0]);
+            return EXIT_INVALID_USAGE;
         }
     }
 
diff --git a/tools/xkbcli-interactive-evdev.1.ronn b/tools/xkbcli-interactive-evdev.1.ronn
index b3d98f4..6b81837 100644
--- a/tools/xkbcli-interactive-evdev.1.ronn
+++ b/tools/xkbcli-interactive-evdev.1.ronn
@@ -17,36 +17,33 @@ stable.
   * `--help`:
       Print help and exit
 
-  * `-r`:
-      Specify the XKB ruleset
+  * `--rules <rules>`:
+      The XKB ruleset
 
-  * `-m`:
-      Specify the XKB model
+  * `--model <model>`:
+      The XKB model
 
-  * `-l`:
-      Specify the XKB layout
+  * `--layout <layout>`:
+      The XKB layout
 
-  * `-v`:
-      Specify the XKB variant
+  * `--variant <variant>`:
+      The XKB layout variant
 
-  * `-o`:
-      Specify the XKB options
+  * `--options <options>`:
+      The XKB options
 
-  * `-k`:
+  * `--keymap`:
       Specify a keymap path. This option is mutually exclusive with the rmlvo
       options.
 
-  * `-n`:
-      Specify an evdev keycode offset.
-
-  * `-c`:
+  * `--report-state-changes`:
       Report changes to the keyboard state
 
-  * `-d`:
+  * `--enable-compose`:
       Enable compose functionality
 
-  * `-g`:
-      Use GTK consumed mode
+  * `--consumed-mode={gtk|xkb}`:
+      Set the consumed modifiers mode (default: xkb)
 
 
 ## SEE ALSO