Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8754337 authored by Jeff Brown's avatar Jeff Brown
Browse files

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
parent 5f05f830
Loading
Loading
Loading
Loading
+174 −19
Original line number Original line Diff line number Diff line
@@ -8,9 +8,11 @@
#include <sys/inotify.h>
#include <sys/inotify.h>
#include <sys/limits.h>
#include <sys/limits.h>
#include <sys/poll.h>
#include <sys/poll.h>
#include <linux/input.h> // this does not compile
#include <linux/input.h>
#include <errno.h>
#include <errno.h>


#include "getevent.h"

static struct pollfd *ufds;
static struct pollfd *ufds;
static char **device_names;
static char **device_names;
static int nfds;
static int nfds;
@@ -22,15 +24,62 @@ enum {
    PRINT_DEVICE_INFO       = 1U << 3,
    PRINT_DEVICE_INFO       = 1U << 3,
    PRINT_VERSION           = 1U << 4,
    PRINT_VERSION           = 1U << 4,
    PRINT_POSSIBLE_EVENTS   = 1U << 5,
    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;
    uint8_t *bits = NULL;
    ssize_t bits_size = 0;
    ssize_t bits_size = 0;
    const char* label;
    const char* label;
    int i, j, k;
    int i, j, k;
    int res, res2;
    int res, res2;
    struct label* bit_labels;
    const char *bit_label;


    printf("  events:\n");
    printf("  events:\n");
    for(i = 0; i <= EV_MAX; i++) {
    for(i = 0; i <= EV_MAX; i++) {
@@ -42,7 +91,7 @@ static int print_possible_events(int fd)
            bits_size = res + 16;
            bits_size = res + 16;
            bits = realloc(bits, bits_size * 2);
            bits = realloc(bits, bits_size * 2);
            if(bits == NULL) {
            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;
                return 1;
            }
            }
        }
        }
@@ -50,44 +99,60 @@ static int print_possible_events(int fd)
        switch(i) {
        switch(i) {
            case EV_SYN:
            case EV_SYN:
                label = "SYN";
                label = "SYN";
                bit_labels = syn_labels;
                break;
                break;
            case EV_KEY:
            case EV_KEY:
                res2 = ioctl(fd, EVIOCGKEY(res), bits + bits_size);
                res2 = ioctl(fd, EVIOCGKEY(res), bits + bits_size);
                label = "KEY";
                label = "KEY";
                bit_labels = key_labels;
                break;
                break;
            case EV_REL:
            case EV_REL:
                label = "REL";
                label = "REL";
                bit_labels = rel_labels;
                break;
                break;
            case EV_ABS:
            case EV_ABS:
                label = "ABS";
                label = "ABS";
                bit_labels = abs_labels;
                break;
                break;
            case EV_MSC:
            case EV_MSC:
                label = "MSC";
                label = "MSC";
                bit_labels = msc_labels;
                break;
                break;
            case EV_LED:
            case EV_LED:
                res2 = ioctl(fd, EVIOCGLED(res), bits + bits_size);
                res2 = ioctl(fd, EVIOCGLED(res), bits + bits_size);
                label = "LED";
                label = "LED";
                bit_labels = led_labels;
                break;
                break;
            case EV_SND:
            case EV_SND:
                res2 = ioctl(fd, EVIOCGSND(res), bits + bits_size);
                res2 = ioctl(fd, EVIOCGSND(res), bits + bits_size);
                label = "SND";
                label = "SND";
                bit_labels = snd_labels;
                break;
                break;
            case EV_SW:
            case EV_SW:
                res2 = ioctl(fd, EVIOCGSW(bits_size), bits + bits_size);
                res2 = ioctl(fd, EVIOCGSW(bits_size), bits + bits_size);
                label = "SW ";
                label = "SW ";
                bit_labels = sw_labels;
                break;
                break;
            case EV_REP:
            case EV_REP:
                label = "REP";
                label = "REP";
                bit_labels = rep_labels;
                break;
                break;
            case EV_FF:
            case EV_FF:
                label = "FF ";
                label = "FF ";
                bit_labels = ff_labels;
                break;
                break;
            case EV_PWR:
            case EV_PWR:
                label = "PWR";
                label = "PWR";
                bit_labels = NULL;
                break;
            case EV_FF_STATUS:
                label = "FFS";
                bit_labels = ff_status_labels;
                break;
                break;
            default:
            default:
                res2 = 0;
                res2 = 0;
                label = "???";
                label = "???";
                bit_labels = NULL;
        }
        }
        for(j = 0; j < res; j++) {
        for(j = 0; j < res; j++) {
            for(k = 0; k < 8; k++)
            for(k = 0; k < 8; k++)
@@ -99,13 +164,21 @@ static int print_possible_events(int fd)
                        down = ' ';
                        down = ' ';
                    if(count == 0)
                    if(count == 0)
                        printf("    %s (%04x):", label, i);
                        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("\n               ");
                    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);
                        printf(" %04x%c", j * 8 + k, down);
                    }
                    if(i == EV_ABS) {
                    if(i == EV_ABS) {
                        struct input_absinfo abs;
                        struct input_absinfo abs;
                        if(ioctl(fd, EVIOCGABS(j * 8 + k), &abs) == 0) {
                        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++;
                    count++;
@@ -118,6 +191,73 @@ static int print_possible_events(int fd)
    return 0;
    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)
static int open_device(const char *device, int print_flags)
{
{
    int version;
    int version;
@@ -193,7 +333,11 @@ static int open_device(const char *device, int print_flags)
               version >> 16, (version >> 8) & 0xff, version & 0xff);
               version >> 16, (version >> 8) & 0xff, version & 0xff);


    if(print_flags & PRINT_POSSIBLE_EVENTS) {
    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;
    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[])
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, "    -t: show time stamps\n");
    fprintf(stderr, "    -n: don't print newlines\n");
    fprintf(stderr, "    -n: don't print newlines\n");
    fprintf(stderr, "    -s: print switch states for given bits\n");
    fprintf(stderr, "    -s: print switch states for given bits\n");
    fprintf(stderr, "    -S: print all switch states\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, "    -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, "    -q: quiet (clear verbosity mask)\n");
    fprintf(stderr, "    -c: print given number of events then exit\n");
    fprintf(stderr, "    -c: print given number of events then exit\n");
    fprintf(stderr, "    -r: print rate events are received\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;
    uint16_t get_switch = 0;
    struct input_event event;
    struct input_event event;
    int version;
    int version;
    int print_flags = PRINT_DEVICE_ERRORS | PRINT_DEVICE | PRINT_DEVICE_NAME;
    int print_flags = 0;
    int print_flags_set = 0;
    int print_flags_set = 0;
    int dont_block = -1;
    int dont_block = -1;
    int event_count = 0;
    int event_count = 0;
@@ -327,7 +473,7 @@ int getevent_main(int argc, char *argv[])


    opterr = 0;
    opterr = 0;
    do {
    do {
        c = getopt(argc, argv, "tns:Sv::pqc:rh");
        c = getopt(argc, argv, "tns:Sv::pilqc:rh");
        if (c == EOF)
        if (c == EOF)
            break;
            break;
        switch (c) {
        switch (c) {
@@ -349,19 +495,27 @@ int getevent_main(int argc, char *argv[])
            break;
            break;
        case 'v':
        case 'v':
            if(optarg)
            if(optarg)
                print_flags =  strtoul(optarg, NULL, 0);
                print_flags |= strtoul(optarg, NULL, 0);
            else
            else
                print_flags |= PRINT_DEVICE | PRINT_DEVICE_NAME | PRINT_DEVICE_INFO | PRINT_VERSION;
                print_flags |= PRINT_DEVICE | PRINT_DEVICE_NAME | PRINT_DEVICE_INFO | PRINT_VERSION;
            print_flags_set = 1;
            print_flags_set = 1;
            break;
            break;
        case 'p':
        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;
            print_flags_set = 1;
            if(dont_block == -1)
            if(dont_block == -1)
                dont_block = 1;
                dont_block = 1;
            break;
            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':
        case 'q':
            print_flags = 0;
            print_flags_set = 1;
            print_flags_set = 1;
            break;
            break;
        case 'c':
        case 'c':
@@ -396,13 +550,14 @@ int getevent_main(int argc, char *argv[])
    ufds[0].events = POLLIN;
    ufds[0].events = POLLIN;
    if(device) {
    if(device) {
        if(!print_flags_set)
        if(!print_flags_set)
            print_flags = PRINT_DEVICE_ERRORS;
            print_flags |= PRINT_DEVICE_ERRORS;
        res = open_device(device, print_flags);
        res = open_device(device, print_flags);
        if(res < 0) {
        if(res < 0) {
            return 1;
            return 1;
        }
        }
    }
    } else {
    else {
        if(!print_flags_set)
            print_flags |= PRINT_DEVICE_ERRORS | PRINT_DEVICE | PRINT_DEVICE_NAME;
        print_device = 1;
        print_device = 1;
		res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE);
		res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE);
        if(res < 0) {
        if(res < 0) {
@@ -451,7 +606,7 @@ int getevent_main(int argc, char *argv[])
                    }
                    }
                    if(print_device)
                    if(print_device)
                        printf("%s: ", device_names[i]);
                        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) {
                    if(sync_rate && event.type == 0 && event.code == 0) {
                        int64_t now = event.time.tv_sec * 1000000LL + event.time.tv_usec;
                        int64_t now = event.time.tv_sec * 1000000LL + event.time.tv_usec;
                        if(last_sync_time)
                        if(last_sync_time)

toolbox/getevent.h

0 → 100644
+725 −0

File added.

Preview size limit exceeded, changes collapsed.