#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)
{
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,
};
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;
{ "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;
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)
}
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 =
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");
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);