chiark / gitweb /
hostside: hidrawconv: cope with difference between 2.6.26 and 2.6.33, guessing the...
[trains.git] / hostside / hidrawconv.c
index 6151b0ade984162544fadf9c1200625d1a379be5..3321ccf701aa517a1a475b27db361d56fd971e62 100644 (file)
@@ -5,6 +5,7 @@
  * where -a means all, and the other letters are:
  *   -d   print expected descriptor (as for hidraw-ioctl -d)
  *   -e   pretend to be evdev-manip
+ *   -E   pretend to be evdev-manip, print to stderr about the device at start
  * exit status:
  *   0      all ok
  *   other  some other problem
@@ -48,6 +49,11 @@ void reportlocs(const uint8_t msg[], const uint8_t last[],
 void dispatch(LastReports *lasts, const char *message_prefix,
              ProcessReport *const report_processors[MAXREPORTS],
              const uint8_t *msg, int l) {
+  if (!l) {
+    fprintf(stderr,"%s:%s report too short\n", progname, message_prefix);
+    return;
+  }
+
   ProcessReport *pr= report_processors[msg[0]];
   Last *last= &lasts->lasts[msg[0]];
   if (!pr) {
@@ -66,13 +72,37 @@ void dispatch(LastReports *lasts, const char *message_prefix,
   memcpy(last->msg, msg, l);
 }  
 
-static void events(void) {
-  uint8_t msg[MAXREPORTLEN];
+static void events(int verbose) {
+  uint8_t msg[MAXREPORTLEN+1];
+  char phys[PATH_MAX], name[PATH_MAX];
+  int rphys, errnophys=0, rname, errnoname=0;
+  int reportnumbug;
+
+  rphys= ioctl(0, HIDIOCGRAWPHYS(PATH_MAX), phys);  errnophys=errno;
+  rname= ioctl(0, HIDIOCGRAWNAME(PATH_MAX), name);  errnoname=errno;
+  if (rphys>=0 && rname>=0) {
+    reportnumbug= 0;
+    if (verbose)
+      fprintf(stderr,"%s: %.*s %.*s\n",progname,rphys,phys,rname,name);
+  } else if (rphys<0 && errnophys==EINVAL &&
+            rname<0 && errnoname==EINVAL) {
+    fprintf(stderr,"%s: warning, HIDIOCGRAWPHYS/NAME gave EINVAL,"
+           " assuming kernel eats report number, assuming reports are 00\n",
+           progname);
+    reportnumbug= 1;
+  } else {
+    die("HIDIOCGRAWPHYS %s / HIDIOCGRAWNAME %s",
+       rphys<0 ? strerror(errnophys) : "ok",
+       rname<0 ? strerror(errnoname) : "ok");
+  }
+
+  if (reportnumbug) msg[0]=0;
 
   for (;;) {
-    int l= read(0, msg, sizeof(msg));
+    int l= read(0, msg+reportnumbug, sizeof(msg)-reportnumbug);
     if (!l) break;
     if (l<0) { perror("hidrawconv: read"); exit(-1); }
+    l += reportnumbug;
     dispatch(&lasts,"",report_processors, msg,l);
     if (ferror(stdout) || fflush(stdout))
       diee("failed flushing event to stdout");
@@ -83,15 +113,19 @@ int main(int argc, char **argv) {
   const char *how;
 
   if (!*argv || !(how=*++argv) || *how++!='-' || !*how || how[1] || *++argv)
-    badusage("need exactly one argument, -d or -e");
+    badusage("need exactly one argument, -d, -e or -E");
 
   switch (how[0]) {
   case 'd':
     puts(descriptor);
     break;
 
+  case 'E':
+    events(1);
+    break;
+
   case 'e':
-    events();
+    events(0);
     break;
 
   default: