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