char buf[INP_BUF_SZ];
int len;
+ short mot[6];
+ unsigned int keystate;
+
int (*parse)(struct sball*, int, char*, int);
};
static void make_printable(char *buf, int len);
static int read_timeout(int fd, char *buf, int bufsz, long tm_usec);
+static void print_state(struct sball *sb);
+
+
struct sball *sball_open(const char *dev)
{
int fd, sz;
if((sz = read_timeout(fd, buf, sizeof buf - 1, 250000)) > 0 && buf[0] == 'v') {
make_printable(buf, sz);
- printf("Magellan SpaceMouse detected: %s\n", buf);
+ printf("Magellan SpaceMouse detected:\n%s\n", buf);
sb->nbuttons = guess_num_buttons(buf);
printf("%d buttons\n", sb->nbuttons);
return 0;
}
+int sball_axis(struct sball *sb, int axis)
+{
+ return sb->mot[axis];
+}
+
+unsigned int sball_buttons(struct sball *sb)
+{
+ return sb->keystate;
+}
+
+int sball_num_buttons(struct sball *sb)
+{
+ return sb->nbuttons;
+}
+
/* Labtec spaceball: 9600 8n1 XON/XOFF */
static int stty_sball(int fd)
{
return 0;
}
-static void print_keystate(unsigned int keystate)
-{
- int i;
-
- printf("keystate: ");
- for(i=0; i<12; i++) {
- int b = 11 - i;
- int hex = b < 10 ? b + '0' : b - 10 + 'a';
- putchar(keystate & (1 << b) ? hex : '-');
- }
- putchar('\n');
-}
-
static int mag_parsepkt(struct sball *sb, int id, char *data, int len)
{
- int i, mot[6];
- unsigned int keystate;
+ int i;
/*printf("magellan packet: %c - %s (%d bytes)\n", (char)id, data, len);*/
return -1;
}
for(i=0; i<6; i++) {
- mot[i] = ((((int)data[0] & 0xf) << 12) | (((int)data[1] & 0xf) << 8) |
+#ifdef SBALL_BIG_ENDIAN
+ sb->mot[i] = ((((int)data[3] & 0xf) << 12) | (((int)data[2] & 0xf) << 8) |
+ (((int)data[1] & 0xf) << 4) | (data[0] & 0xf)) - 0x8000;
+#else
+ sb->mot[i] = ((((int)data[0] & 0xf) << 12) | (((int)data[1] & 0xf) << 8) |
(((int)data[2] & 0xf) << 4) | (data[3] & 0xf)) - 0x8000;
+#endif
data += 4;
}
- printf("motion: T %+4d %+4d %+4d R %+4d %+4d %+4d\n", mot[0], mot[1], mot[2], mot[3], mot[4], mot[5]);
+ print_state(sb);
break;
case 'k':
fprintf(stderr, "magellan: invalid keyboard pakcet, expected 3 bytes, got: %d\n", len);
return -1;
}
- keystate = (data[0] & 0xf) | ((data[1] & 0xf) << 4) | (((unsigned int)data[2] & 0xf) << 8);
- print_keystate(keystate);
+ sb->keystate = (data[0] & 0xf) | ((data[1] & 0xf) << 4) | (((unsigned int)data[2] & 0xf) << 8);
+ print_state(sb);
break;
case 'e':
static int sball_parsepkt(struct sball *sb, int id, char *data, int len)
{
int i;
- unsigned int keystate;
char c, *rd, *wr;
- short *mot;
/* decode data packet, replacing escaped values with the correct ones */
rd = wr = data;
break;
case '^':
*wr++ = '^';
+ break;
default:
fprintf(stderr, "sball decode: ignoring invalid escape code: %xh\n", (unsigned int)c);
}
return -1;
}
- mot = (short*)(data + 2); /* skip the period */
- printf("motion: T %+6d %+6d %+6d R %+6d %+6d %+6d\n", mot[0], mot[1], mot[2], mot[3], mot[4], mot[5]);
+#ifndef SBALL_BIG_ENDIAN
+ for(i=0; i<6; i++) {
+ data += 2;
+ c = data[0];
+ data[0] = data[1];
+ data[1] = c;
+ sb->mot[i] = *(short*)data;
+ }
+#else
+ memcpy(sb->mot, data + 2, 12);
+#endif
+ print_state(sb);
break;
case 'K':
* data[0] bits 0-2 -> buttons 4,5,6
* data[0] bit 4 is (2003 pick) -> button 7
*/
- keystate = (data[1] & 0xf) | ((data[1] >> 4) & 3) | ((data[0] & 7) << 4) |
+ sb->keystate = (data[1] & 0xf) | ((data[1] >> 4) & 3) | ((data[0] & 7) << 4) |
((data[0] & 0x10) >> 1);
- print_keystate(keystate);
+ print_state(sb);
break;
case '.':
}
/* spaceball 4000 key packet */
sb->flags |= SB4000;
- /* update orientation flag */
+ /* update orientation flag (actually don't bother) */
+ /*
if(data[0] & 0x20) {
sb->flags |= FLIPXY;
} else {
sb->flags &= ~FLIPXY;
}
+ */
/* data[1] bits 0-5 -> buttons 0,1,2,3,4,5
* data[1] bit 7 -> button 6
* data[0] bits 0-4 -> buttons 7,8,9,10,11
*/
- keystate = (data[1] & 0x3f) | ((data[1] & 0x80) >> 1) | ((data[0] & 0x1f) << 7);
- print_keystate(keystate);
+ sb->keystate = (data[1] & 0x3f) | ((data[1] & 0x80) >> 1) | ((data[0] & 0x1f) << 7);
+ print_state(sb);
break;
case 'E':
}
break;
+ case 'M': /* ignore MSS responses */
+ break;
+
default:
/* DEBUG */
fprintf(stderr, "sball: got '%c' packet:", (char)id);
}
}
- if(strstr(verstr, "MAGELLAN Version")) {
+ if(strstr(verstr, "MAGELLAN")) {
return 9; /* magellan spacemouse */
}
- if(strstr(verstr, "SPACEBALL Version")) {
+ if(strstr(verstr, "SPACEBALL")) {
return 12; /* spaceball 5000 */
}
- if(strstr(verstr, "CadMan Version")) {
+ if(strstr(verstr, "CadMan")) {
return 2;
}
return sz > 0 ? sz : -1;
}
+static void print_motion(short *mot)
+{
+ printf(" T[%+6d %+6d %+6d] R[%+6d %+6d %+6d]", mot[0], mot[1],
+ mot[2], mot[3], mot[4], mot[5]);
+}
+
+static void print_keystate(unsigned int keystate)
+{
+ int i;
+
+ for(i=0; i<12; i++) {
+ int b = 11 - i;
+ int hex = b < 10 ? b + '0' : b - 10 + 'a';
+ putchar(keystate & (1 << b) ? hex : '-');
+ }
+}
+
+static void print_state(struct sball *sb)
+{
+ print_motion(sb->mot);
+ printf(" B[");
+ print_keystate(sb->keystate);
+ printf("]\r");
+ fflush(stdout);
+}