void *froot;
HiddevField *fbuf;
} hiddev;
+ struct {
+ int nabsinfos;
+ struct input_absinfo **absinfos;
+ } evdev;
} forkind;
};
/*---------- evdev kind ----------*/
+static const struct input_absinfo *evdev_getabsinfo(Device *d, uint16_t code) {
+ struct input_absinfo **aip, *ai;
+ int i, r;
+
+ if (code >= 0x80) return 0; /* absurd ioctl scheme! */
+
+ if (code >= d->forkind.evdev.nabsinfos) {
+ int newsize= code+10;
+ d->forkind.evdev.absinfos= mrealloc(d->forkind.evdev.absinfos,
+ newsize * sizeof(*d->forkind.evdev.absinfos));
+ for (i=d->forkind.evdev.nabsinfos; i<newsize; i++)
+ d->forkind.evdev.absinfos[i]= 0;
+ }
+ aip= &d->forkind.evdev.absinfos[code];
+ ai= *aip;
+ if (ai) return ai;
+
+ *aip= ai= mmalloc(sizeof(*ai));
+ r= ioctl(d->fd, EVIOCGABS(code), ai);
+ ai->value= r ? errno : 0;
+ return ai;
+}
+
static void evdev_dump(Device *d, const struct input_event *ie) {
const InputEventTypeInfo *t;
-
+ const struct input_absinfo *ai;
printf("evdev ");
pr_time(ie->time);
printf(" ");
switch (ie->type) {
case EV_ABS:
+ ai= evdev_getabsinfo(d, ie->code);
+ if (!ai) {
+ printf("?");
+ } else if (ai->value) {
+ printf("?%ld [%s]", (long)ie->value, strerror(ai->value));
+ break;
+ } else if ((ai->minimum==-1 || ai->minimum== 0) &&
+ (ai->maximum== 0 || ai->maximum==+1)) {
+ } else if (ai) {
+ printf("%.7f",
+ (double)(ie->value - ai->minimum)/(ai->maximum - ai->minimum));
+ break;
+ }
+ /* fall through */
case EV_REL:
printf("%ld",(long)ie->value);
break;
r= ioctl(d->fd, EVIOCGRAB, 1);
if (r) diee("%s: failed to grab",d->path);
}
+
+ d->forkind.evdev.nabsinfos= 0;
+ d->forkind.evdev.absinfos= 0;
}
static const KindInfo kind_evdev= { evdev_prepare, evdev_readable };