From: Peter Hutterer Date: Mon, 29 Jun 2015 00:44:10 +0000 (+1000) Subject: tools - tweak-device: revamp to reduce use of globals X-Git-Tag: libevdev-1.4.4~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4d058bc2b04f85b06ebb8a66c7462007b7a30212;p=platform%2Fupstream%2Flibevdev.git tools - tweak-device: revamp to reduce use of globals 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 Reviewed-by: Benjamin Tissoires --- diff --git a/tools/libevdev-tweak-device.c b/tools/libevdev-tweak-device.c index 21cd69c..b28da02 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,85 +81,147 @@ 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 }, }; if (argc < 2) goto error; + optind = 1; while (1) { c = getopt_long(argc, argv, "h", opts, &option_index); if (c == -1) 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; + + optind = 1; + 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; } - if (optind >= argc) - goto error; - path = argv[optind]; - 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", 1, 0, OPT_ABS }, + { "led", 1, 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) + return MODE_NONE; + + *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 +237,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 +256,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 +284,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 +328,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);