[PATCH libevdev 1/2] tools - tweak-device: revamp to reduce use of globals
Peter Hutterer
peter.hutterer at who-t.net
Tue Jun 30 00:21:00 PDT 2015
Make the code base a bit more modular so it's easier to add new commands.
Main change here is: options are parsed twice now, first time for the mode
(abs/led) and the device path, then again for the mode-specific options.
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
tools/libevdev-tweak-device.c | 213 ++++++++++++++++++++++++++++++------------
1 file changed, 151 insertions(+), 62 deletions(-)
diff --git a/tools/libevdev-tweak-device.c b/tools/libevdev-tweak-device.c
index 21cd69c..3d1cd23 100644
--- a/tools/libevdev-tweak-device.c
+++ b/tools/libevdev-tweak-device.c
@@ -37,13 +37,6 @@
#include "libevdev.h"
-static unsigned int changes; /* bitmask of changes */
-static struct input_absinfo absinfo;
-static int axis;
-static int led;
-static int led_state = -1;
-const char *path;
-
static void
usage(void)
{
@@ -54,6 +47,13 @@ usage(void)
program_invocation_short_name, program_invocation_short_name);
}
+enum mode {
+ MODE_NONE = 0,
+ MODE_ABS,
+ MODE_LED,
+ MODE_HELP,
+};
+
enum opts {
OPT_ABS = 1 << 0,
OPT_MIN = 1 << 1,
@@ -68,7 +68,8 @@ enum opts {
};
static int
-parse_options(int argc, char **argv)
+parse_options_abs(int argc, char **argv, unsigned int *changes,
+ int *axis, struct input_absinfo *absinfo)
{
int rc = 1;
int c;
@@ -80,10 +81,6 @@ parse_options(int argc, char **argv)
{ "fuzz", 1, 0, OPT_FUZZ },
{ "flat", 1, 0, OPT_FLAT },
{ "res", 1, 0, OPT_RES },
- { "led", 1, 0, OPT_LED },
- { "on", 0, 0, OPT_ON },
- { "off", 0, 0, OPT_OFF },
- { "help", 0, 0, OPT_HELP },
{ NULL, 0, 0, 0 },
};
@@ -96,69 +93,133 @@ parse_options(int argc, char **argv)
break;
switch (c) {
- case 'h':
- case OPT_HELP:
- goto error;
case OPT_ABS:
- if (changes & OPT_LED)
- goto error;
-
- axis = libevdev_event_code_from_name(EV_ABS,
+ *axis = libevdev_event_code_from_name(EV_ABS,
optarg);
- if (axis == -1)
- goto error;
- break;
- case OPT_LED:
- if (changes & OPT_ABS)
- goto error;
-
- led = libevdev_event_code_from_name(EV_LED,
- optarg);
- if (led == -1)
+ if (*axis == -1)
goto error;
break;
case OPT_MIN:
- absinfo.minimum = atoi(optarg);
+ absinfo->minimum = atoi(optarg);
break;
case OPT_MAX:
- absinfo.maximum = atoi(optarg);
+ absinfo->maximum = atoi(optarg);
break;
case OPT_FUZZ:
- absinfo.fuzz = atoi(optarg);
+ absinfo->fuzz = atoi(optarg);
break;
case OPT_FLAT:
- absinfo.flat = atoi(optarg);
+ absinfo->flat = atoi(optarg);
break;
case OPT_RES:
- absinfo.resolution = atoi(optarg);
+ absinfo->resolution = atoi(optarg);
+ break;
+ default:
+ goto error;
+ }
+ *changes |= c;
+ }
+ rc = 0;
+error:
+ return rc;
+}
+
+static int
+parse_options_led(int argc, char **argv, int *led, int *led_state)
+{
+ int rc = 1;
+ int c;
+ int option_index = 0;
+ static struct option opts[] = {
+ { "led", 1, 0, OPT_LED },
+ { "on", 0, 0, OPT_ON },
+ { "off", 0, 0, OPT_OFF },
+ { NULL, 0, 0, 0 },
+ };
+
+ if (argc < 2)
+ goto error;
+
+ while (1) {
+ c = getopt_long(argc, argv, "h", opts, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case OPT_LED:
+ *led = libevdev_event_code_from_name(EV_LED,
+ optarg);
+ if (*led == -1)
+ goto error;
break;
case OPT_ON:
- if (led_state != -1)
+ if (*led_state != -1)
goto error;
- led_state = 1;
+ *led_state = 1;
break;
case OPT_OFF:
- if (led_state != -1)
+ if (*led_state != -1)
goto error;
- led_state = 0;
+ *led_state = 0;
break;
default:
goto error;
}
- changes |= c;
+ }
+
+ rc = 0;
+error:
+ return rc;
+}
+
+static enum mode
+parse_options_mode(int argc, char **argv, const char **path)
+{
+ int c;
+ int option_index = 0;
+ static const struct option opts[] = {
+ { "abs", 0, 0, OPT_ABS },
+ { "led", 0, 0, OPT_LED },
+ { "help", 0, 0, OPT_HELP },
+ { NULL, 0, 0, 0 },
+ };
+ enum mode mode = MODE_NONE;
+
+ if (argc < 2)
+ return mode;
+
+ while (1) {
+ c = getopt_long(argc, argv, "h", opts, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'h':
+ case OPT_HELP:
+ mode = MODE_HELP;
+ break;
+ case OPT_ABS:
+ mode = MODE_ABS;
+ break;
+ case OPT_LED:
+ mode = MODE_LED;
+ break;
+ default:
+ break;
+ }
}
if (optind >= argc)
- goto error;
- path = argv[optind];
+ return MODE_NONE;
- rc = 0;
-error:
- return rc;
+ *path = argv[optind];
+
+ return mode;
}
static void
-set_abs(struct libevdev *dev)
+set_abs(struct libevdev *dev, unsigned int changes,
+ unsigned int axis, struct input_absinfo *absinfo)
{
int rc;
struct input_absinfo abs;
@@ -174,15 +235,15 @@ set_abs(struct libevdev *dev)
abs = *a;
if (changes & OPT_MIN)
- abs.minimum = absinfo.minimum;
+ abs.minimum = absinfo->minimum;
if (changes & OPT_MAX)
- abs.maximum = absinfo.maximum;
+ abs.maximum = absinfo->maximum;
if (changes & OPT_FUZZ)
- abs.fuzz = absinfo.fuzz;
+ abs.fuzz = absinfo->fuzz;
if (changes & OPT_FLAT)
- abs.flat = absinfo.flat;
+ abs.flat = absinfo->flat;
if (changes & OPT_RES)
- abs.resolution = absinfo.resolution;
+ abs.resolution = absinfo->resolution;
rc = libevdev_kernel_set_abs_info(dev, axis, &abs);
if (rc != 0)
@@ -193,7 +254,7 @@ set_abs(struct libevdev *dev)
}
static void
-set_led(struct libevdev *dev)
+set_led(struct libevdev *dev, unsigned int led, int led_state)
{
int rc;
enum libevdev_led_value state =
@@ -221,13 +282,38 @@ main(int argc, char **argv)
struct libevdev *dev = NULL;
int fd = -1;
int rc = 1;
+ enum mode mode;
+ const char *path;
+ struct input_absinfo absinfo;
+ int axis;
+ int led;
+ int led_state = -1;
+ unsigned int changes; /* bitmask of changes */
- rc = parse_options(argc, argv);
- if (rc != 0 || !path) {
- usage();
- goto out;
+ mode = parse_options_mode(argc, argv, &path);
+ switch (mode) {
+ case MODE_HELP:
+ rc = EXIT_SUCCESS;
+ /* fallthrough */
+ case MODE_NONE:
+ usage();
+ goto out;
+ case MODE_ABS:
+ rc = parse_options_abs(argc, argv, &changes, &axis,
+ &absinfo);
+ break;
+ case MODE_LED:
+ rc = parse_options_led(argc, argv, &led, &led_state);
+ break;
+ default:
+ fprintf(stderr,
+ "++?????++ Out of Cheese Error. Redo From Start.\n");
+ goto out;
}
+ if (rc != EXIT_SUCCESS)
+ goto out;
+
fd = open(path, O_RDWR);
if (fd < 0) {
perror("Failed to open device");
@@ -240,13 +326,16 @@ main(int argc, char **argv)
goto out;
}
- if (changes & OPT_ABS)
- set_abs(dev);
- else if (changes & OPT_LED)
- set_led(dev);
- else
- fprintf(stderr,
- "++?????++ Out of Cheese Error. Redo From Start.\n");
+ switch (mode) {
+ case MODE_ABS:
+ set_abs(dev, changes, axis, &absinfo);
+ break;
+ case MODE_LED:
+ set_led(dev, led, led_state);
+ break;
+ default:
+ break;
+ }
out:
libevdev_free(dev);
--
2.4.3
More information about the Input-tools
mailing list