* --[no-]grab --nograb is default
*/
-#include <input.h>
-
#include "common.h"
-typedef struct {
- void (*onevent)();
- void (*mainloop)();
-} ModeInfo;
+#include <poll.h>
+#include <sys/fcntl.h>
-typedef const ModeInfo *Mode;
+#include <linux/input.h>
+#include "input-codes.h" /* not really a header */
typedef struct {
char *path;
int fd;
} Device;
+typedef struct {
+ void (*event)(Device *d, const struct input_event *ie);
+ void (*mainloop)(void);
+} ModeInfo;
+
+typedef const ModeInfo *Mode;
+
static int ndevices;
static Device *devices;
static Mode mode;
static int grab;
-static void mode_dump(void) {
+static void pr_hexdec(unsigned long value) { printf("%#lx %ld",value,value); }
+
+#define PR_TABLE_STR(tab, val) (pr_table_str(iesis_##tab, iesin_##tab, (val)))
+static void pr_table_str(const InputEventStringInfo *strings, int nstrings,
+ unsigned long value) {
+ const InputEventStringInfo *string;
+ if (value > nstrings) { pr_hexdec(value); return; }
+ string= &strings[value];
+ if (!string->prefix) { pr_hexdec(value); return; }
+ printf("%s %s", string->prefix, string->main);
+}
+
+static void dump_event(Device *d, const struct input_event *ie) {
+ const InputEventTypeInfo *t;
+
+ printf("event ");
+ PR_TABLE_STR(ev, ie->type);
+
+ printf(" ");
+ if (ie->type >= IETIN) {
+ t= 0;
+ } else {
+ t= &ietis[ie->type];
+ if (!t->strings) t= 0;
+ }
+ if (t) pr_table_str(t->strings, t->nstrings, ie->code);
+ else pr_hexdec(ie->code);
+
+ printf(" ");
+ switch (ie->type) {
+ case EV_ABS:
+ case EV_REL:
+ printf("%ld",(long)ie->value);
+ break;
+ default:
+ printf("%lx",(unsigned long)ie->value);
+ break;
+ }
+ printf("\n");
}
static void process_device(Device *d) {
printf("event-group-start device %s\n",d->path);
for (;;) {
- for (p=&ie, remain=sizeof(ie);
+ for (p=(void*)&ie, remain=sizeof(ie);
remain;
p+=r, remain-=r) {
r= read(d->fd, &ie, remain);
if (ie.type == EV_SYN) {
printf("synchronised %ju.%06d\n",
(uintmax_t)ie.time.tv_sec,
- (int)ie.time_tv_usec);
+ (int)ie.time.tv_usec);
break;
}
-
+
+ mode->event(d, &ie);
+ }
+ mflushstdout();
}
static void mainloop(void) {
struct pollfd *polls;
+ int i, r;
polls= mmalloc(sizeof(*polls)*ndevices);
for (i=0; i<ndevices; i++) {
for (i=0; i<ndevices; i++)
polls[i].revents= 0;
- r= poll(&polls,ndevices,-1);
+ r= poll(polls,ndevices,-1);
if (r==-1) {
if (errno==EINTR) continue;
diee("poll failed");
assert(r>0);
for (i=0; i<ndevices; i++) {
- if (polls[i].revent & ~POLLIN)
+ if (polls[i].revents & ~POLLIN)
die("device %s (fd %d) gave unexpected poll revent %#x",
- devices[i].path, devices[i].fd, polls[i].revent);
- if (polls[i].revent)
+ devices[i].path, devices[i].fd, polls[i].revents);
+ if (polls[i].revents)
process_device(&devices[i]);
}
}
}
+static const ModeInfo mode_dump= { dump_event, mainloop };
+
static void getdevice(const char *path) {
int r;
struct input_id iid;
d->fd= open(path, O_RDONLY); if (d->fd<0) diee("%s: failed to open",path);
r= ioctl(d->fd, EVIOCGID, &iid); if (r) diee("%s: failed to get id",path);
- printf("device %s bustype %#x vendor %#x product #%x version %#x\n"
- path, iid.bustype, iid.vendor, iid.product, iid.version);
+ printf("device %s bustype ", path);
+ PR_TABLE_STR(bus, iid.bustype);
+ printf(" vendor %#x product #%x version %#x\n",
+ iid.vendor, iid.product, iid.version);
mflushstdout();
if (grab)
if (arg[0] != '-') {
getdevice(arg);
}
- else if (!strcmp(arg,"--dump")) { mode= mode_dump; }
+ else if (!strcmp(arg,"--dump")) { mode= &mode_dump; }
else if (!strcmp(arg,"--grab")) { grab= 1; }
else if (!strcmp(arg,"--no-grab")) { grab= 0; }
- else badusage("unknown option `%s'",arg);
+ else badusage("unknown option");
}
mode->mainloop();
return 0;
}
+
+const char *progname= "evdev-manip";
+void die_hook(void) { }
+void die_vprintf_hook(const char *fmt, va_list al) { }
# "/usr/include/linux/input.h
-our (%strs, %checkunique);
+our (%strs, %checkunique, %tabaliases, %evtypes);
sub strs ($) {
my ($t) = @_;
}
sub evtype ($) {
my ($t) = @_;
+ $evtypes{$t}= 1;
strs($t);
}
foreach $t (qw(KEY REL ABS MSC LED)) {
evtype($t);
}
-$strs{'BTN'}= $strs{'KEY'};
+$tabaliases{'BTN'}= 'KEY';
-our ($tab,$str,$val);
+our ($tab,$str,$val,$s);
while (<>) {
if (m/^\#define (\w+)_(\w+)\s+(0|[1-9]\d+|0x[0-9a-f]+)\s*$/) {
next if "${tab}_${str}" =~
m/^BTN_(?:MISC|MOUSE|JOYSTICK|GAMEPAD|DIGI)$|^EV_VERSION$/;
next if $str eq 'MAX';
- if (exists($strs{$tab})) {
- die "$tab $str $val" if defined $strs{$tab}[$val];
- $strs{$tab}[$val]= $str;
+ $t= $tabaliases{$tab} || $tab;
+ $s= $strs{$t};
+ if (defined $s) {
+ die "$tab $str $val" if defined $s->[$val];
+ $s->[$val]= [ $tab, $str ];
}
- die "$tab $str $val" if $checkunique{$tab}{$str}++;
+ die "$tab $str $val" if $checkunique{$t}{"$tab $str"}++;
}
}
-our ($s,$i);
+our ($i,$iesis,$iesin,$n,$si);
+
+print <<END
+typedef struct {
+ const char *prefix, *main;
+} InputEventStringInfo;
+
+typedef struct {
+ int nstrings;
+ const InputEventStringInfo *strings;
+} InputEventTypeInfo;
+
+END
+ or die $!;
+
+sub print_i () {
+ printf " /* %4d %#6x */ ", $i,$i or die $!;
+}
for $t (sort keys %strs) {
- printf "static const char *iesis_%s[]= {\n", lc $t
- or die $!;
$s= $strs{$t};
+ $n= @$s;
+ $iesin= "IESIN_$t";
+ $iesis= "iesis_\L$t";
+ print <<END
+#define $iesin $n
+static const int \L$iesin\E= $n;
+static const InputEventStringInfo ${iesis}[$iesin] = {
+END
+ or die $!;
for ($i=0; $i<@$s; $i++) {
- printf " %s,\n", (defined $s->[$i] ? "\"$s->[$i]\"" : "0")
- or die $!;
+ $si= $s->[$i];
+ print_i();
+ if (defined $si) {
+ printf " { %10s %-25s },\n", "\"$si->[0]\",", "\"$si->[1]\""
+ or die $!;
+ } else {
+ print " { 0 },\n"
+ or die $!;
+ }
}
printf "};\n"
or die $!;
}
+
+for $tab (sort keys %tabaliases) {
+ $t= $tabaliases{$tab};
+ print <<END
+#define IESIN_${tab} IESIN_${t}
+#define iesis_\L${tab} iesis_${t}
+END
+ or die $!;
+}
+
+$s= $strs{'EV'};
+print <<END
+#define IETIN IESIN_EV
+static const InputEventTypeInfo ietis[IETIN]= {
+END
+ or die $!;
+
+our (@sip);
+
+for ($i=0; $i<@$s; $i++) {
+ $si= $s->[$i];
+ $tab= defined $si ? $si->[1] : undef;
+ $tab= $tab && exists $evtypes{$tab} ? $tab : undef;
+ @sip= $tab ? ("IESIN_$tab", "iesis_\L$tab") : ("-1", "0");
+ print_i();
+ printf " { %-21s %-20s },\n", "$sip[0],", $sip[1]
+ or die $!;
+}
+print <<END
+};
+END
+ or die $!;