X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=sball;a=blobdiff_plain;f=src%2Fsball.c;h=2de14031f17cc5184c04fdc45a24bcbbbec8836c;hp=7e5101ac46dfc9a97e331bcc8e0d45198bf79dc8;hb=aae3666f514af7606db0fe34c601bfdafa4cb7dc;hpb=aeeaea66849f23d8dec42bb64c9a739846a835d9 diff --git a/src/sball.c b/src/sball.c index 7e5101a..2de1403 100644 --- a/src/sball.c +++ b/src/sball.c @@ -1,24 +1,36 @@ #include #include #include +#include #include #include #include #include +#include +#include struct sball { int fd; + + int (*decode)(struct sball *sb, char *line); }; static int stty_sball(int fd); static int stty_mag(int fd); +static int decode_sball(struct sball *sb, char *line); +static int decode_mag(struct sball *sb, char *line); + +static void make_printable(char *buf, int len); +static int read_timeout(int fd, char *buf, int bufsz, long tm_usec); + struct sball *sball_open(const char *dev) { - int fd; + int fd, sz; + char buf[128]; struct sball *sb = 0; - if((fd = open(dev, O_RDWR | | O_NOCTTY | O_NONBLOCK)) == -1) { + if((fd = open(dev, O_RDWR | O_NOCTTY)) == -1) { fprintf(stderr, "sball_open: failed to open device: %s: %s\n", dev, strerror(errno)); return 0; } @@ -33,9 +45,29 @@ struct sball *sball_open(const char *dev) goto err; } - /* set detect receiver function pointer */ + if((sz = read_timeout(fd, buf, sizeof buf - 1, 2000000)) > 0) { + /* we got a response, so it's a spaceball */ + make_printable(buf, sz); + printf("Spaceball detected: %s\n", buf); + + sb->decode = decode_sball; + return sb; + } + + /* try as a magellan spacemouse */ + if(stty_mag(fd) == -1) { + goto err; + } + write(fd, "vQ\r", 3); + + if((sz = read_timeout(fd, buf, sizeof buf - 1, 250000)) > 0) { + /* we got a response, it's a magellan spacemouse */ + make_printable(buf, sz); + printf("Magellan SpaceMouse detected: %s\n", buf); - return sb; + sb->decode = decode_mag; + return sb; + } err: close(fd); @@ -63,13 +95,13 @@ static int stty_sball(int fd) term.c_oflag = 0; term.c_lflag = 0; term.c_cc[VMIN] = 0; - term.c_cc[VTIME] = 0; + term.c_cc[VTIME] = 1; term.c_cflag = CLOCAL | CREAD | CS8 | HUPCL; term.c_iflag = IGNBRK | IGNPAR | IXON | IXOFF; - csetispeed(&term, B9600); - csetospeed(&term, B9600); + cfsetispeed(&term, B9600); + cfsetospeed(&term, B9600); if(tcsetattr(fd, TCSANOW, &term) == -1) { perror("sball_open: tcsetattr"); @@ -92,13 +124,13 @@ static int stty_mag(int fd) term.c_oflag = 0; term.c_lflag = 0; term.c_cc[VMIN] = 0; - term.c_cc[VTIME] = 0; + term.c_cc[VTIME] = 1; term.c_cflag = CLOCAL | CREAD | CS8 | CSTOPB | HUPCL | CRTSCTS; - term.c_iflag = IGNBRK | IGNPAR |; + term.c_iflag = IGNBRK | IGNPAR | ICRNL; - csetispeed(&term, B9600); - csetospeed(&term, B9600); + cfsetispeed(&term, B9600); + cfsetospeed(&term, B9600); if(tcsetattr(fd, TCSANOW, &term) == -1) { perror("sball_open: tcsetattr"); @@ -107,3 +139,67 @@ static int stty_mag(int fd) return 0; } + + +static int decode_sball(struct sball *sb, char *line) +{ + return -1; +} + +static int decode_mag(struct sball *sb, char *line) +{ + return -1; +} + +static void make_printable(char *buf, int len) +{ + int i, c; + char *wr = buf; + + for(i=0; i 0) { + tv.tv_sec = usec / 1000000; + tv.tv_usec = usec % 1000000; + + FD_ZERO(&rdset); + FD_SET(fd, &rdset); + if((res = select(fd + 1, &rdset, 0, 0, &tv)) > 0 && FD_ISSET(fd, &rdset)) { + sz += read(fd, buf + sz, bufsz - sz); + buf[sz] = 0; + tm_usec = usec = 128000; /* wait 128ms for the rest of the message to appear */ + gettimeofday(&tv0, 0); + continue; + } + if(res == -1 && (errno == EWOULDBLOCK || errno == EAGAIN)) { + break; + } + gettimeofday(&tv, 0); + usec = tm_usec - ((tv.tv_sec - tv0.tv_sec) * 1000000 + (tv.tv_usec - tv0.tv_usec)); + } + + return sz > 0 ? sz : -1; +} +