chiark / gitweb /
762133ec9670bf515a9e41b9e97b2a5f5a991165
[trains.git] / hostside / hidrawconv.c
1 /*
2  * usage:
3  *   .../hidrawconv-<controller> -d
4  *   .../hidrawconv-<controller> -e </dev/hidrawN
5  * where -a means all, and the other letters are:
6  *   -d   print expected descriptor (as for hidraw-ioctl -d)
7  *   -e   pretend to be evdev-manip
8  * exit status:
9  *   0      all ok
10  *   other  some other problem
11  *
12  * joystick values are always doubles from -1 to 0 to +1
13  */
14
15 #include "hidrawconv.h"
16
17 void die_vprintf_hook(const char *fmt, va_list al) { }
18 void die_hook(void) { }
19
20 typedef struct { int len; uint8_t *msg; } Last;
21 static Last lasts[MAXREPORTS];
22
23 void reportbits(const uint8_t msg[], const uint8_t last[],
24                 int len, const KeyBit *bit) {
25   for (; bit->str; bit++) {
26     if (bit->pos >= len) continue;
27     uint8_t m= msg[bit->pos] & bit->mask;
28     uint8_t l= last[bit->pos] & bit->mask;
29     if (m==l) continue;
30     printf("%s %d\n", bit->str, !!m);
31   }
32 }
33
34 void reportlocs(const uint8_t msg[], const uint8_t last[],
35                 int len, const ValLoc *loc) {
36   for (; loc->str; loc++) {
37     if (loc->pos >= len) continue;
38     uint8_t mb= msg[loc->pos] & loc->mask;
39     uint8_t lb= last[loc->pos] & loc->mask;
40     if (mb==lb) continue;
41     mb >>= loc->rshift;
42     mb -= loc->zero;
43     double val= (int8_t)mb;
44     val /= (val >= 0 ? 127 : 128);
45     printf("%s %.5f\n", loc->str, loc->sign * val);
46   }
47 }
48   
49 static void events(void) {
50   uint8_t msg[MAXREPORTLEN];
51   for (;;) {
52     int l= read(0, msg, sizeof(msg));
53     if (!l) break;
54     if (l<0) { perror("hidrawconv: read"); exit(-1); }
55     ProcessReport *pr= report_processors[msg[0]];
56     Last *last= &lasts[msg[0]];
57     if (!pr) {
58       if (!last->len)
59         fprintf(stderr,"%s: unexpected report 0x%02x\n", progname, msg[0]);
60       last->len= l;
61       continue;
62     }
63     if (last->len < l) {
64       last->msg= mrealloc(last->msg, l);
65       memset(last->msg + last->len, 0, l - last->len);
66       last->len= l;
67     }
68     pr(msg, l, last->msg);
69     if (ferror(stdout) || fflush(stdout))
70       diee("failed flushing event to stdout");
71     memcpy(last->msg, msg, l);
72   }
73 }
74
75 int main(int argc, char **argv) {
76   const char *how;
77
78   if (!*argv || !(how=*++argv) || *how++!='-' || !*how || how[1] || *++argv)
79     badusage("need exactly one argument, -d or -e");
80
81   switch (how[0]) {
82   case 'd':
83     puts(descriptor);
84     break;
85
86   case 'e':
87     events();
88     break;
89
90   default:
91     badusage("unknown option/mode");
92   }
93
94   if (ferror(stdout) || fflush(stdout))
95     diee("write/flush stdout");
96
97   return 0;
98 }