chiark / gitweb /
hostside: evdev-manip: print floating point values -1..+1 for ABS values
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sun, 13 Feb 2011 12:40:55 +0000 (12:40 +0000)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sun, 13 Feb 2011 12:40:55 +0000 (12:40 +0000)
hostside/evdev-manip.c

index 72d52ee8f580688c07b6c2b4192a9144c598b230..d7edefe4814751799d85862cd0ea3c4c5751a15b 100644 (file)
@@ -125,6 +125,10 @@ struct Device {
       void *froot;
       HiddevField *fbuf;
     } hiddev;
+    struct {
+      int nabsinfos;
+      struct input_absinfo **absinfos;
+    } evdev;
   } forkind;
 };
 
@@ -179,9 +183,32 @@ static void dump_vpv(unsigned vendor, unsigned product, unsigned version) {
 
 /*---------- 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);
 
@@ -201,6 +228,20 @@ static void evdev_dump(Device *d, const struct input_event *ie) {
   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;
@@ -330,6 +371,9 @@ static void evdev_prepare(Device *d) {
     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 };