/* * Copyright © 2013 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include "libevdev.h" static void print_abs_bits(struct libevdev *dev, int axis) { const struct input_absinfo *abs; if (!libevdev_has_event_code(dev, EV_ABS, axis)) return; abs = libevdev_get_abs_info(dev, axis); printf(" Value %6d\n", abs->value); printf(" Min %6d\n", abs->minimum); printf(" Max %6d\n", abs->maximum); if (abs->fuzz) printf(" Fuzz %6d\n", abs->fuzz); if (abs->flat) printf(" Flat %6d\n", abs->flat); if (abs->resolution) printf(" Resolution %6d\n", abs->resolution); } static void print_code_bits(struct libevdev *dev, unsigned int type, unsigned int max) { unsigned int i; for (i = 0; i <= max; i++) { if (!libevdev_has_event_code(dev, type, i)) continue; printf(" Event code %i (%s)\n", i, libevdev_event_code_get_name(type, i)); if (type == EV_ABS) print_abs_bits(dev, i); } } static void print_bits(struct libevdev *dev) { unsigned int i; printf("Supported events:\n"); for (i = 0; i <= EV_MAX; i++) { if (libevdev_has_event_type(dev, i)) printf(" Event type %d (%s)\n", i, libevdev_event_type_get_name(i)); switch(i) { case EV_KEY: print_code_bits(dev, EV_KEY, KEY_MAX); break; case EV_REL: print_code_bits(dev, EV_REL, REL_MAX); break; case EV_ABS: print_code_bits(dev, EV_ABS, ABS_MAX); break; case EV_LED: print_code_bits(dev, EV_LED, LED_MAX); break; } } } static void print_props(struct libevdev *dev) { unsigned int i; printf("Properties:\n"); for (i = 0; i <= INPUT_PROP_MAX; i++) { if (libevdev_has_property(dev, i)) printf(" Property type %d (%s)\n", i, libevdev_get_property_name(i)); } } int print_event(struct input_event *ev) { if (ev->type == EV_SYN) printf("Event: time %ld.%06ld, ++++++++++++++++++++ %s +++++++++++++++\n", ev->time.tv_sec, ev->time.tv_usec, libevdev_event_type_get_name(ev->type)); else printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n", ev->time.tv_sec, ev->time.tv_usec, ev->type, libevdev_event_type_get_name(ev->type), ev->code, libevdev_event_code_get_name(ev->type, ev->code), ev->value); return 0; } int print_sync_event(struct input_event *ev) { printf("SYNC: "); print_event(ev); return 0; } int main(int argc, char **argv) { struct libevdev *dev = NULL; const char *file; int fd; int rc = 1; if (argc < 2) goto out; file = argv[1]; fd = open(file, O_RDONLY); if (fd < 0) { perror("Failed to open device"); goto out; } rc = libevdev_new_from_fd(fd, &dev); if (rc < 0) { fprintf(stderr, "Failed to init libevdev (%s)\n", strerror(-rc)); goto out; } printf("Input device ID: bus %#x vendor %#x product %#x\n", libevdev_get_id_bustype(dev), libevdev_get_id_vendor(dev), libevdev_get_id_product(dev)); printf("Evdev version: %x\n", libevdev_get_driver_version(dev)); printf("Input device name: \"%s\"\n", libevdev_get_name(dev)); printf("Phys location: %s\n", libevdev_get_phys(dev)); printf("Uniq identifier: %s\n", libevdev_get_uniq(dev)); print_bits(dev); print_props(dev); do { struct input_event ev; rc = libevdev_next_event(dev, LIBEVDEV_READ_NORMAL|LIBEVDEV_READ_BLOCKING, &ev); if (rc == 1) { printf("::::::::::::::::::::: dropped ::::::::::::::::::::::\n"); while (rc == 1) { print_sync_event(&ev); rc = libevdev_next_event(dev, LIBEVDEV_READ_SYNC, &ev); } printf("::::::::::::::::::::: re-synced ::::::::::::::::::::::\n"); } else if (rc == 0) print_event(&ev); } while (rc == 1 || rc == 0 || rc == -EAGAIN); if (rc != 0 && rc != -EAGAIN) fprintf(stderr, "Failed to handle events: %s\n", strerror(rc)); rc = 0; out: libevdev_free(dev); return rc; }