diff options
author | Jeff Brown <jeffbrown@google.com> | 2011-06-15 17:44:52 -0700 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2011-06-15 17:44:52 -0700 |
commit | f8754337d82d0a1ba509311bbadd281619c7d96e (patch) | |
tree | 22cc556083a6f05b603b668184fd282b5d412e84 /toolbox/getevent.c | |
parent | 5f05f83075857c499a83f36e347c1ef49501a0dd (diff) | |
download | system_core-f8754337d82d0a1ba509311bbadd281619c7d96e.zip system_core-f8754337d82d0a1ba509311bbadd281619c7d96e.tar.gz system_core-f8754337d82d0a1ba509311bbadd281619c7d96e.tar.bz2 |
Enhance getevent to print event labels.
Added -l argument to print labels for event types, codes and values.
Added -i argument to print all device info.
Added support for printing input properties.
Change-Id: I3cacb716dbc38f50217b9dfc24ba44d08f352603
Diffstat (limited to 'toolbox/getevent.c')
-rw-r--r-- | toolbox/getevent.c | 193 |
1 files changed, 174 insertions, 19 deletions
diff --git a/toolbox/getevent.c b/toolbox/getevent.c index 256720d..f0a6c24 100644 --- a/toolbox/getevent.c +++ b/toolbox/getevent.c @@ -8,9 +8,11 @@ #include <sys/inotify.h> #include <sys/limits.h> #include <sys/poll.h> -#include <linux/input.h> // this does not compile +#include <linux/input.h> #include <errno.h> +#include "getevent.h" + static struct pollfd *ufds; static char **device_names; static int nfds; @@ -22,16 +24,63 @@ enum { PRINT_DEVICE_INFO = 1U << 3, PRINT_VERSION = 1U << 4, PRINT_POSSIBLE_EVENTS = 1U << 5, + PRINT_INPUT_PROPS = 1U << 6, + + PRINT_ALL_INFO = (1U << 7) - 1, + + PRINT_LABELS = 1U << 16, }; -static int print_possible_events(int fd) +static const char *get_label(const struct label *labels, int value) +{ + while(labels->name && value != labels->value) { + labels++; + } + return labels->name; +} + +static int print_input_props(int fd) +{ + uint8_t bits[INPUT_PROP_CNT / 8]; + int i, j; + int res; + int count; + const char *bit_label; + + printf(" input props:\n"); + res = ioctl(fd, EVIOCGPROP(sizeof(bits)), bits); + if(res < 0) { + printf(" <not available\n"); + return 1; + } + count = 0; + for(i = 0; i < res; i++) { + for(j = 0; j < 8; j++) { + if (bits[i] & 1 << j) { + bit_label = get_label(input_prop_labels, i * 8 + j); + if(bit_label) + printf(" %s\n", bit_label); + else + printf(" %04x\n", i * 8 + j); + count++; + } + } + } + if (!count) + printf(" <none>\n"); + return 0; +} + +static int print_possible_events(int fd, int print_flags) { uint8_t *bits = NULL; ssize_t bits_size = 0; const char* label; int i, j, k; int res, res2; - + struct label* bit_labels; + const char *bit_label; + printf(" events:\n"); for(i = 0; i <= EV_MAX; i++) { int count = 0; @@ -42,7 +91,7 @@ static int print_possible_events(int fd) bits_size = res + 16; bits = realloc(bits, bits_size * 2); if(bits == NULL) { - fprintf(stderr, "failed to allocate buffer of size %d\n", bits_size); + fprintf(stderr, "failed to allocate buffer of size %d\n", (int)bits_size); return 1; } } @@ -50,44 +99,60 @@ static int print_possible_events(int fd) switch(i) { case EV_SYN: label = "SYN"; + bit_labels = syn_labels; break; case EV_KEY: res2 = ioctl(fd, EVIOCGKEY(res), bits + bits_size); label = "KEY"; + bit_labels = key_labels; break; case EV_REL: label = "REL"; + bit_labels = rel_labels; break; case EV_ABS: label = "ABS"; + bit_labels = abs_labels; break; case EV_MSC: label = "MSC"; + bit_labels = msc_labels; break; case EV_LED: res2 = ioctl(fd, EVIOCGLED(res), bits + bits_size); label = "LED"; + bit_labels = led_labels; break; case EV_SND: res2 = ioctl(fd, EVIOCGSND(res), bits + bits_size); label = "SND"; + bit_labels = snd_labels; break; case EV_SW: res2 = ioctl(fd, EVIOCGSW(bits_size), bits + bits_size); label = "SW "; + bit_labels = sw_labels; break; case EV_REP: label = "REP"; + bit_labels = rep_labels; break; case EV_FF: label = "FF "; + bit_labels = ff_labels; break; case EV_PWR: label = "PWR"; + bit_labels = NULL; + break; + case EV_FF_STATUS: + label = "FFS"; + bit_labels = ff_status_labels; break; default: res2 = 0; label = "???"; + bit_labels = NULL; } for(j = 0; j < res; j++) { for(k = 0; k < 8; k++) @@ -99,13 +164,21 @@ static int print_possible_events(int fd) down = ' '; if(count == 0) printf(" %s (%04x):", label, i); - else if((count & 0x7) == 0 || i == EV_ABS) + else if((count & (print_flags & PRINT_LABELS ? 0x3 : 0x7)) == 0 || i == EV_ABS) printf("\n "); - printf(" %04x%c", j * 8 + k, down); + if(bit_labels && (print_flags & PRINT_LABELS)) { + bit_label = get_label(bit_labels, j * 8 + k); + if(bit_label) + printf(" %.20s%c%*s", bit_label, down, 20 - strlen(bit_label), ""); + else + printf(" %04x%c ", j * 8 + k, down); + } else { + printf(" %04x%c", j * 8 + k, down); + } if(i == EV_ABS) { struct input_absinfo abs; if(ioctl(fd, EVIOCGABS(j * 8 + k), &abs) == 0) { - printf(" value %d, min %d, max %d, fuzz %d flat %d", abs.value, abs.minimum, abs.maximum, abs.fuzz, abs.flat); + printf(" : value %d, min %d, max %d, fuzz %d flat %d", abs.value, abs.minimum, abs.maximum, abs.fuzz, abs.flat); } } count++; @@ -118,6 +191,73 @@ static int print_possible_events(int fd) return 0; } +static void print_event(int type, int code, int value, int print_flags) +{ + const char *type_label, *code_label, *value_label; + + if (print_flags & PRINT_LABELS) { + type_label = get_label(ev_labels, type); + code_label = NULL; + value_label = NULL; + + switch(type) { + case EV_SYN: + code_label = get_label(syn_labels, code); + break; + case EV_KEY: + code_label = get_label(key_labels, code); + value_label = get_label(key_value_labels, value); + break; + case EV_REL: + code_label = get_label(rel_labels, code); + break; + case EV_ABS: + code_label = get_label(abs_labels, code); + switch(code) { + case ABS_MT_TOOL_TYPE: + value_label = get_label(mt_tool_labels, value); + } + break; + case EV_MSC: + code_label = get_label(msc_labels, code); + break; + case EV_LED: + code_label = get_label(led_labels, code); + break; + case EV_SND: + code_label = get_label(snd_labels, code); + break; + case EV_SW: + code_label = get_label(sw_labels, code); + break; + case EV_REP: + code_label = get_label(rep_labels, code); + break; + case EV_FF: + code_label = get_label(ff_labels, code); + break; + case EV_FF_STATUS: + code_label = get_label(ff_status_labels, code); + break; + } + + if (type_label) + printf("%-12.12s", type_label); + else + printf("%04x ", type); + if (code_label) + printf(" %-20.20s", code_label); + else + printf(" %04x ", code); + if (value_label) + printf(" %-20.20s", value_label); + else + printf(" %08x ", code); + } else { + printf("%04x %04x %08x", type, code, value); + } +} + static int open_device(const char *device, int print_flags) { int version; @@ -193,7 +333,11 @@ static int open_device(const char *device, int print_flags) version >> 16, (version >> 8) & 0xff, version & 0xff); if(print_flags & PRINT_POSSIBLE_EVENTS) { - print_possible_events(fd); + print_possible_events(fd, print_flags); + } + + if(print_flags & PRINT_INPUT_PROPS) { + print_input_props(fd); } ufds[nfds].fd = fd; @@ -292,13 +436,15 @@ static int scan_dir(const char *dirname, int print_flags) static void usage(int argc, char *argv[]) { - fprintf(stderr, "Usage: %s [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-p] [-q] [-c count] [-r] [device]\n", argv[0]); + fprintf(stderr, "Usage: %s [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-p] [-i] [-l] [-q] [-c count] [-r] [device]\n", argv[0]); fprintf(stderr, " -t: show time stamps\n"); fprintf(stderr, " -n: don't print newlines\n"); fprintf(stderr, " -s: print switch states for given bits\n"); fprintf(stderr, " -S: print all switch states\n"); - fprintf(stderr, " -v: verbosity mask (errs=1, dev=2, name=4, info=8, vers=16, pos. events=32)\n"); + fprintf(stderr, " -v: verbosity mask (errs=1, dev=2, name=4, info=8, vers=16, pos. events=32, props=64)\n"); fprintf(stderr, " -p: show possible events (errs, dev, name, pos. events)\n"); + fprintf(stderr, " -i: show all device info and possible events\n"); + fprintf(stderr, " -l: label event types and names in plain text\n"); fprintf(stderr, " -q: quiet (clear verbosity mask)\n"); fprintf(stderr, " -c: print given number of events then exit\n"); fprintf(stderr, " -r: print rate events are received\n"); @@ -316,7 +462,7 @@ int getevent_main(int argc, char *argv[]) uint16_t get_switch = 0; struct input_event event; int version; - int print_flags = PRINT_DEVICE_ERRORS | PRINT_DEVICE | PRINT_DEVICE_NAME; + int print_flags = 0; int print_flags_set = 0; int dont_block = -1; int event_count = 0; @@ -327,7 +473,7 @@ int getevent_main(int argc, char *argv[]) opterr = 0; do { - c = getopt(argc, argv, "tns:Sv::pqc:rh"); + c = getopt(argc, argv, "tns:Sv::pilqc:rh"); if (c == EOF) break; switch (c) { @@ -349,19 +495,27 @@ int getevent_main(int argc, char *argv[]) break; case 'v': if(optarg) - print_flags = strtoul(optarg, NULL, 0); + print_flags |= strtoul(optarg, NULL, 0); else print_flags |= PRINT_DEVICE | PRINT_DEVICE_NAME | PRINT_DEVICE_INFO | PRINT_VERSION; print_flags_set = 1; break; case 'p': - print_flags = PRINT_DEVICE_ERRORS | PRINT_DEVICE | PRINT_DEVICE_NAME | PRINT_POSSIBLE_EVENTS; + print_flags |= PRINT_DEVICE_ERRORS | PRINT_DEVICE | PRINT_DEVICE_NAME | PRINT_POSSIBLE_EVENTS; print_flags_set = 1; if(dont_block == -1) dont_block = 1; break; + case 'i': + print_flags |= PRINT_ALL_INFO; + print_flags_set = 1; + if(dont_block == -1) + dont_block = 1; + break; + case 'l': + print_flags |= PRINT_LABELS; + break; case 'q': - print_flags = 0; print_flags_set = 1; break; case 'c': @@ -396,13 +550,14 @@ int getevent_main(int argc, char *argv[]) ufds[0].events = POLLIN; if(device) { if(!print_flags_set) - print_flags = PRINT_DEVICE_ERRORS; + print_flags |= PRINT_DEVICE_ERRORS; res = open_device(device, print_flags); if(res < 0) { return 1; } - } - else { + } else { + if(!print_flags_set) + print_flags |= PRINT_DEVICE_ERRORS | PRINT_DEVICE | PRINT_DEVICE_NAME; print_device = 1; res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE); if(res < 0) { @@ -451,7 +606,7 @@ int getevent_main(int argc, char *argv[]) } if(print_device) printf("%s: ", device_names[i]); - printf("%04x %04x %08x", event.type, event.code, event.value); + print_event(event.type, event.code, event.value, print_flags); if(sync_rate && event.type == 0 && event.code == 0) { int64_t now = event.time.tv_sec * 1000000LL + event.time.tv_usec; if(last_sync_time) |