1c0abf9e6Sopenharmony_ci// SPDX-License-Identifier: MIT 2c0abf9e6Sopenharmony_ci/* 3c0abf9e6Sopenharmony_ci * Copyright © 2013 Red Hat, Inc. 4c0abf9e6Sopenharmony_ci */ 5c0abf9e6Sopenharmony_ci 6c0abf9e6Sopenharmony_ci#include "config.h" 7c0abf9e6Sopenharmony_ci 8c0abf9e6Sopenharmony_ci#include <assert.h> 9c0abf9e6Sopenharmony_ci#include <errno.h> 10c0abf9e6Sopenharmony_ci#include <fcntl.h> 11c0abf9e6Sopenharmony_ci#include <linux/input.h> 12c0abf9e6Sopenharmony_ci#include <stdio.h> 13c0abf9e6Sopenharmony_ci#include <string.h> 14c0abf9e6Sopenharmony_ci#include <sys/stat.h> 15c0abf9e6Sopenharmony_ci#include <sys/types.h> 16c0abf9e6Sopenharmony_ci 17c0abf9e6Sopenharmony_ci#include "libevdev/libevdev.h" 18c0abf9e6Sopenharmony_ci 19c0abf9e6Sopenharmony_cistatic void 20c0abf9e6Sopenharmony_ciprint_abs_bits(struct libevdev *dev, int axis) 21c0abf9e6Sopenharmony_ci{ 22c0abf9e6Sopenharmony_ci const struct input_absinfo *abs; 23c0abf9e6Sopenharmony_ci 24c0abf9e6Sopenharmony_ci if (!libevdev_has_event_code(dev, EV_ABS, axis)) 25c0abf9e6Sopenharmony_ci return; 26c0abf9e6Sopenharmony_ci 27c0abf9e6Sopenharmony_ci abs = libevdev_get_abs_info(dev, axis); 28c0abf9e6Sopenharmony_ci 29c0abf9e6Sopenharmony_ci printf(" Value %6d\n", abs->value); 30c0abf9e6Sopenharmony_ci printf(" Min %6d\n", abs->minimum); 31c0abf9e6Sopenharmony_ci printf(" Max %6d\n", abs->maximum); 32c0abf9e6Sopenharmony_ci if (abs->fuzz) 33c0abf9e6Sopenharmony_ci printf(" Fuzz %6d\n", abs->fuzz); 34c0abf9e6Sopenharmony_ci if (abs->flat) 35c0abf9e6Sopenharmony_ci printf(" Flat %6d\n", abs->flat); 36c0abf9e6Sopenharmony_ci if (abs->resolution) 37c0abf9e6Sopenharmony_ci printf(" Resolution %6d\n", abs->resolution); 38c0abf9e6Sopenharmony_ci} 39c0abf9e6Sopenharmony_ci 40c0abf9e6Sopenharmony_cistatic void 41c0abf9e6Sopenharmony_ciprint_code_bits(struct libevdev *dev, unsigned int type, unsigned int max) 42c0abf9e6Sopenharmony_ci{ 43c0abf9e6Sopenharmony_ci unsigned int i; 44c0abf9e6Sopenharmony_ci for (i = 0; i <= max; i++) { 45c0abf9e6Sopenharmony_ci if (!libevdev_has_event_code(dev, type, i)) 46c0abf9e6Sopenharmony_ci continue; 47c0abf9e6Sopenharmony_ci 48c0abf9e6Sopenharmony_ci printf(" Event code %i (%s)\n", i, libevdev_event_code_get_name(type, i)); 49c0abf9e6Sopenharmony_ci if (type == EV_ABS) 50c0abf9e6Sopenharmony_ci print_abs_bits(dev, i); 51c0abf9e6Sopenharmony_ci } 52c0abf9e6Sopenharmony_ci} 53c0abf9e6Sopenharmony_ci 54c0abf9e6Sopenharmony_cistatic void 55c0abf9e6Sopenharmony_ciprint_bits(struct libevdev *dev) 56c0abf9e6Sopenharmony_ci{ 57c0abf9e6Sopenharmony_ci unsigned int i; 58c0abf9e6Sopenharmony_ci printf("Supported events:\n"); 59c0abf9e6Sopenharmony_ci 60c0abf9e6Sopenharmony_ci for (i = 0; i <= EV_MAX; i++) { 61c0abf9e6Sopenharmony_ci if (libevdev_has_event_type(dev, i)) 62c0abf9e6Sopenharmony_ci printf(" Event type %d (%s)\n", i, libevdev_event_type_get_name(i)); 63c0abf9e6Sopenharmony_ci switch(i) { 64c0abf9e6Sopenharmony_ci case EV_KEY: 65c0abf9e6Sopenharmony_ci print_code_bits(dev, EV_KEY, KEY_MAX); 66c0abf9e6Sopenharmony_ci break; 67c0abf9e6Sopenharmony_ci case EV_REL: 68c0abf9e6Sopenharmony_ci print_code_bits(dev, EV_REL, REL_MAX); 69c0abf9e6Sopenharmony_ci break; 70c0abf9e6Sopenharmony_ci case EV_ABS: 71c0abf9e6Sopenharmony_ci print_code_bits(dev, EV_ABS, ABS_MAX); 72c0abf9e6Sopenharmony_ci break; 73c0abf9e6Sopenharmony_ci case EV_LED: 74c0abf9e6Sopenharmony_ci print_code_bits(dev, EV_LED, LED_MAX); 75c0abf9e6Sopenharmony_ci break; 76c0abf9e6Sopenharmony_ci } 77c0abf9e6Sopenharmony_ci } 78c0abf9e6Sopenharmony_ci} 79c0abf9e6Sopenharmony_ci 80c0abf9e6Sopenharmony_cistatic void 81c0abf9e6Sopenharmony_ciprint_props(struct libevdev *dev) 82c0abf9e6Sopenharmony_ci{ 83c0abf9e6Sopenharmony_ci unsigned int i; 84c0abf9e6Sopenharmony_ci printf("Properties:\n"); 85c0abf9e6Sopenharmony_ci 86c0abf9e6Sopenharmony_ci for (i = 0; i <= INPUT_PROP_MAX; i++) { 87c0abf9e6Sopenharmony_ci if (libevdev_has_property(dev, i)) 88c0abf9e6Sopenharmony_ci printf(" Property type %d (%s)\n", i, 89c0abf9e6Sopenharmony_ci libevdev_property_get_name(i)); 90c0abf9e6Sopenharmony_ci } 91c0abf9e6Sopenharmony_ci} 92c0abf9e6Sopenharmony_ci 93c0abf9e6Sopenharmony_cistatic int 94c0abf9e6Sopenharmony_ciprint_event(struct input_event *ev) 95c0abf9e6Sopenharmony_ci{ 96c0abf9e6Sopenharmony_ci if (ev->type == EV_SYN) 97c0abf9e6Sopenharmony_ci printf("Event: time %ld.%06ld, ++++++++++++++++++++ %s +++++++++++++++\n", 98c0abf9e6Sopenharmony_ci ev->input_event_sec, 99c0abf9e6Sopenharmony_ci ev->input_event_usec, 100c0abf9e6Sopenharmony_ci libevdev_event_type_get_name(ev->type)); 101c0abf9e6Sopenharmony_ci else 102c0abf9e6Sopenharmony_ci printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n", 103c0abf9e6Sopenharmony_ci ev->input_event_sec, 104c0abf9e6Sopenharmony_ci ev->input_event_usec, 105c0abf9e6Sopenharmony_ci ev->type, 106c0abf9e6Sopenharmony_ci libevdev_event_type_get_name(ev->type), 107c0abf9e6Sopenharmony_ci ev->code, 108c0abf9e6Sopenharmony_ci libevdev_event_code_get_name(ev->type, ev->code), 109c0abf9e6Sopenharmony_ci ev->value); 110c0abf9e6Sopenharmony_ci return 0; 111c0abf9e6Sopenharmony_ci} 112c0abf9e6Sopenharmony_ci 113c0abf9e6Sopenharmony_cistatic int 114c0abf9e6Sopenharmony_ciprint_sync_event(struct input_event *ev) 115c0abf9e6Sopenharmony_ci{ 116c0abf9e6Sopenharmony_ci printf("SYNC: "); 117c0abf9e6Sopenharmony_ci print_event(ev); 118c0abf9e6Sopenharmony_ci return 0; 119c0abf9e6Sopenharmony_ci} 120c0abf9e6Sopenharmony_ci 121c0abf9e6Sopenharmony_ciint 122c0abf9e6Sopenharmony_cimain(int argc, char **argv) 123c0abf9e6Sopenharmony_ci{ 124c0abf9e6Sopenharmony_ci struct libevdev *dev = NULL; 125c0abf9e6Sopenharmony_ci const char *file; 126c0abf9e6Sopenharmony_ci int fd; 127c0abf9e6Sopenharmony_ci int rc = 1; 128c0abf9e6Sopenharmony_ci 129c0abf9e6Sopenharmony_ci if (argc < 2) 130c0abf9e6Sopenharmony_ci goto out; 131c0abf9e6Sopenharmony_ci 132c0abf9e6Sopenharmony_ci file = argv[1]; 133c0abf9e6Sopenharmony_ci fd = open(file, O_RDONLY); 134c0abf9e6Sopenharmony_ci if (fd < 0) { 135c0abf9e6Sopenharmony_ci perror("Failed to open device"); 136c0abf9e6Sopenharmony_ci goto out; 137c0abf9e6Sopenharmony_ci } 138c0abf9e6Sopenharmony_ci 139c0abf9e6Sopenharmony_ci rc = libevdev_new_from_fd(fd, &dev); 140c0abf9e6Sopenharmony_ci if (rc < 0) { 141c0abf9e6Sopenharmony_ci fprintf(stderr, "Failed to init libevdev (%s)\n", strerror(-rc)); 142c0abf9e6Sopenharmony_ci goto out; 143c0abf9e6Sopenharmony_ci } 144c0abf9e6Sopenharmony_ci 145c0abf9e6Sopenharmony_ci printf("Input device ID: bus %#x vendor %#x product %#x\n", 146c0abf9e6Sopenharmony_ci libevdev_get_id_bustype(dev), 147c0abf9e6Sopenharmony_ci libevdev_get_id_vendor(dev), 148c0abf9e6Sopenharmony_ci libevdev_get_id_product(dev)); 149c0abf9e6Sopenharmony_ci printf("Evdev version: %x\n", libevdev_get_driver_version(dev)); 150c0abf9e6Sopenharmony_ci printf("Input device name: \"%s\"\n", libevdev_get_name(dev)); 151c0abf9e6Sopenharmony_ci printf("Phys location: %s\n", libevdev_get_phys(dev)); 152c0abf9e6Sopenharmony_ci printf("Uniq identifier: %s\n", libevdev_get_uniq(dev)); 153c0abf9e6Sopenharmony_ci print_bits(dev); 154c0abf9e6Sopenharmony_ci print_props(dev); 155c0abf9e6Sopenharmony_ci 156c0abf9e6Sopenharmony_ci do { 157c0abf9e6Sopenharmony_ci struct input_event ev; 158c0abf9e6Sopenharmony_ci rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL|LIBEVDEV_READ_FLAG_BLOCKING, &ev); 159c0abf9e6Sopenharmony_ci if (rc == LIBEVDEV_READ_STATUS_SYNC) { 160c0abf9e6Sopenharmony_ci printf("::::::::::::::::::::: dropped ::::::::::::::::::::::\n"); 161c0abf9e6Sopenharmony_ci while (rc == LIBEVDEV_READ_STATUS_SYNC) { 162c0abf9e6Sopenharmony_ci print_sync_event(&ev); 163c0abf9e6Sopenharmony_ci rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev); 164c0abf9e6Sopenharmony_ci } 165c0abf9e6Sopenharmony_ci printf("::::::::::::::::::::: re-synced ::::::::::::::::::::::\n"); 166c0abf9e6Sopenharmony_ci } else if (rc == LIBEVDEV_READ_STATUS_SUCCESS) 167c0abf9e6Sopenharmony_ci print_event(&ev); 168c0abf9e6Sopenharmony_ci } while (rc == LIBEVDEV_READ_STATUS_SYNC || rc == LIBEVDEV_READ_STATUS_SUCCESS || rc == -EAGAIN); 169c0abf9e6Sopenharmony_ci 170c0abf9e6Sopenharmony_ci if (rc != LIBEVDEV_READ_STATUS_SUCCESS && rc != -EAGAIN) 171c0abf9e6Sopenharmony_ci fprintf(stderr, "Failed to handle events: %s\n", strerror(-rc)); 172c0abf9e6Sopenharmony_ci 173c0abf9e6Sopenharmony_ci rc = 0; 174c0abf9e6Sopenharmony_ciout: 175c0abf9e6Sopenharmony_ci libevdev_free(dev); 176c0abf9e6Sopenharmony_ci 177c0abf9e6Sopenharmony_ci return rc; 178c0abf9e6Sopenharmony_ci} 179