1706f2543Smrg/* 2706f2543Smrg * Copyright 2002 Red Hat Inc., Durham, North Carolina. 3706f2543Smrg * 4706f2543Smrg * All Rights Reserved. 5706f2543Smrg * 6706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining 7706f2543Smrg * a copy of this software and associated documentation files (the 8706f2543Smrg * "Software"), to deal in the Software without restriction, including 9706f2543Smrg * without limitation on the rights to use, copy, modify, merge, 10706f2543Smrg * publish, distribute, sublicense, and/or sell copies of the Software, 11706f2543Smrg * and to permit persons to whom the Software is furnished to do so, 12706f2543Smrg * subject to the following conditions: 13706f2543Smrg * 14706f2543Smrg * The above copyright notice and this permission notice (including the 15706f2543Smrg * next paragraph) shall be included in all copies or substantial 16706f2543Smrg * portions of the Software. 17706f2543Smrg * 18706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19706f2543Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20706f2543Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21706f2543Smrg * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS 22706f2543Smrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 23706f2543Smrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24706f2543Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25706f2543Smrg * SOFTWARE. 26706f2543Smrg * 27706f2543Smrg * This is a simple test program that reads from /dev/input/event*, 28706f2543Smrg * decoding events into a human readable form. 29706f2543Smrg */ 30706f2543Smrg 31706f2543Smrg/* 32706f2543Smrg * Authors: 33706f2543Smrg * Rickard E. (Rik) Faith <faith@redhat.com> 34706f2543Smrg * 35706f2543Smrg */ 36706f2543Smrg 37706f2543Smrg#include <stdio.h> 38706f2543Smrg#include <stdlib.h> 39706f2543Smrg#include <unistd.h> 40706f2543Smrg#include <string.h> 41706f2543Smrg#include <sys/types.h> 42706f2543Smrg#include <fcntl.h> 43706f2543Smrg#include <errno.h> 44706f2543Smrg#include <time.h> 45706f2543Smrg#include <linux/input.h> 46706f2543Smrg 47706f2543Smrgstruct input_event event; 48706f2543Smrg 49706f2543Smrgint main(int argc, char **argv) 50706f2543Smrg{ 51706f2543Smrg char name[64]; /* RATS: Use ok, but could be better */ 52706f2543Smrg char buf[256] = { 0, }; /* RATS: Use ok */ 53706f2543Smrg unsigned char mask[EV_MAX/8 + 1]; /* RATS: Use ok */ 54706f2543Smrg int version; 55706f2543Smrg int fd = 0; 56706f2543Smrg int rc; 57706f2543Smrg int i, j; 58706f2543Smrg char *tmp; 59706f2543Smrg 60706f2543Smrg#define test_bit(bit) (mask[(bit)/8] & (1 << ((bit)%8))) 61706f2543Smrg 62706f2543Smrg for (i = 0; i < 32; i++) { 63706f2543Smrg sprintf(name, "/dev/input/event%d", i); 64706f2543Smrg if ((fd = open(name, O_RDONLY, 0)) >= 0) { 65706f2543Smrg ioctl(fd, EVIOCGVERSION, &version); 66706f2543Smrg ioctl(fd, EVIOCGNAME(sizeof(buf)), buf); 67706f2543Smrg ioctl(fd, EVIOCGBIT(0, sizeof(mask)), mask); 68706f2543Smrg printf("%s\n", name); 69706f2543Smrg printf(" evdev version: %d.%d.%d\n", 70706f2543Smrg version >> 16, (version >> 8) & 0xff, version & 0xff); 71706f2543Smrg printf(" name: %s\n", buf); 72706f2543Smrg printf(" features:"); 73706f2543Smrg for (j = 0; j < EV_MAX; j++) { 74706f2543Smrg if (test_bit(j)) { 75706f2543Smrg const char *type = "unknown"; 76706f2543Smrg switch(j) { 77706f2543Smrg case EV_KEY: type = "keys/buttons"; break; 78706f2543Smrg case EV_REL: type = "relative"; break; 79706f2543Smrg case EV_ABS: type = "absolute"; break; 80706f2543Smrg case EV_MSC: type = "reserved"; break; 81706f2543Smrg case EV_LED: type = "leds"; break; 82706f2543Smrg case EV_SND: type = "sound"; break; 83706f2543Smrg case EV_REP: type = "repeat"; break; 84706f2543Smrg case EV_FF: type = "feedback"; break; 85706f2543Smrg } 86706f2543Smrg printf(" %s", type); 87706f2543Smrg } 88706f2543Smrg } 89706f2543Smrg printf("\n"); 90706f2543Smrg close(fd); 91706f2543Smrg } 92706f2543Smrg } 93706f2543Smrg 94706f2543Smrg if (argc > 1) { 95706f2543Smrg sprintf(name, "/dev/input/event%d", atoi(argv[1])); 96706f2543Smrg if ((fd = open(name, O_RDWR, 0)) >= 0) { 97706f2543Smrg printf("%s: open, fd = %d\n", name, fd); 98706f2543Smrg for (i = 0; i < LED_MAX; i++) { 99706f2543Smrg event.time.tv_sec = time(0); 100706f2543Smrg event.time.tv_usec = 0; 101706f2543Smrg event.type = EV_LED; 102706f2543Smrg event.code = i; 103706f2543Smrg event.value = 0; 104706f2543Smrg write(fd, &event, sizeof(event)); 105706f2543Smrg } 106706f2543Smrg 107706f2543Smrg while ((rc = read(fd, &event, sizeof(event))) > 0) { 108706f2543Smrg printf("%-24.24s.%06lu type 0x%04x; code 0x%04x;" 109706f2543Smrg " value 0x%08x; ", 110706f2543Smrg ctime(&event.time.tv_sec), 111706f2543Smrg event.time.tv_usec, 112706f2543Smrg event.type, event.code, event.value); 113706f2543Smrg switch (event.type) { 114706f2543Smrg case EV_KEY: 115706f2543Smrg if (event.code > BTN_MISC) { 116706f2543Smrg printf("Button %d %s", 117706f2543Smrg event.code & 0xff, 118706f2543Smrg event.value ? "press" : "release"); 119706f2543Smrg } else { 120706f2543Smrg printf("Key %d (0x%x) %s", 121706f2543Smrg event.code & 0xff, 122706f2543Smrg event.code & 0xff, 123706f2543Smrg event.value ? "press" : "release"); 124706f2543Smrg } 125706f2543Smrg break; 126706f2543Smrg case EV_REL: 127706f2543Smrg switch (event.code) { 128706f2543Smrg case REL_X: tmp = "X"; break; 129706f2543Smrg case REL_Y: tmp = "Y"; break; 130706f2543Smrg case REL_HWHEEL: tmp = "HWHEEL"; break; 131706f2543Smrg case REL_DIAL: tmp = "DIAL"; break; 132706f2543Smrg case REL_WHEEL: tmp = "WHEEL"; break; 133706f2543Smrg case REL_MISC: tmp = "MISC"; break; 134706f2543Smrg default: tmp = "UNKNOWN"; break; 135706f2543Smrg } 136706f2543Smrg printf("Relative %s %d", tmp, event.value); 137706f2543Smrg break; 138706f2543Smrg case EV_ABS: 139706f2543Smrg switch (event.code) { 140706f2543Smrg case ABS_X: tmp = "X"; break; 141706f2543Smrg case ABS_Y: tmp = "Y"; break; 142706f2543Smrg case ABS_Z: tmp = "Z"; break; 143706f2543Smrg case ABS_RX: tmp = "RX"; break; 144706f2543Smrg case ABS_RY: tmp = "RY"; break; 145706f2543Smrg case ABS_RZ: tmp = "RZ"; break; 146706f2543Smrg case ABS_THROTTLE: tmp = "THROTTLE"; break; 147706f2543Smrg case ABS_RUDDER: tmp = "RUDDER"; break; 148706f2543Smrg case ABS_WHEEL: tmp = "WHEEL"; break; 149706f2543Smrg case ABS_GAS: tmp = "GAS"; break; 150706f2543Smrg case ABS_BRAKE: tmp = "BRAKE"; break; 151706f2543Smrg case ABS_HAT0X: tmp = "HAT0X"; break; 152706f2543Smrg case ABS_HAT0Y: tmp = "HAT0Y"; break; 153706f2543Smrg case ABS_HAT1X: tmp = "HAT1X"; break; 154706f2543Smrg case ABS_HAT1Y: tmp = "HAT1Y"; break; 155706f2543Smrg case ABS_HAT2X: tmp = "HAT2X"; break; 156706f2543Smrg case ABS_HAT2Y: tmp = "HAT2Y"; break; 157706f2543Smrg case ABS_HAT3X: tmp = "HAT3X"; break; 158706f2543Smrg case ABS_HAT3Y: tmp = "HAT3Y"; break; 159706f2543Smrg case ABS_PRESSURE: tmp = "PRESSURE"; break; 160706f2543Smrg case ABS_DISTANCE: tmp = "DISTANCE"; break; 161706f2543Smrg case ABS_TILT_X: tmp = "TILT_X"; break; 162706f2543Smrg case ABS_TILT_Y: tmp = "TILT_Y"; break; 163706f2543Smrg case ABS_MISC: tmp = "MISC"; break; 164706f2543Smrg default: tmp = "UNKNOWN"; break; 165706f2543Smrg } 166706f2543Smrg printf("Absolute %s %d", tmp, event.value); 167706f2543Smrg break; 168706f2543Smrg case EV_MSC: printf("Misc"); break; 169706f2543Smrg case EV_LED: printf("Led"); break; 170706f2543Smrg case EV_SND: printf("Snd"); break; 171706f2543Smrg case EV_REP: printf("Rep"); break; 172706f2543Smrg case EV_FF: printf("FF"); break; 173706f2543Smrg break; 174706f2543Smrg } 175706f2543Smrg printf("\n"); 176706f2543Smrg } 177706f2543Smrg printf("rc = %d, (%s)\n", rc, strerror(errno)); 178706f2543Smrg close(fd); 179706f2543Smrg } 180706f2543Smrg } 181706f2543Smrg return 0; 182706f2543Smrg} 183