9 static void destroy(void);
10 static int detect(void);
11 static int start(void);
12 static void stop(void);
13 static int pending(void);
14 static int getevent(device_event *ev);
16 static int opendev(const char *dev);
17 static int proc_packets(void);
18 static void enqueue_event(device_event *ev);
19 static int parse_motion(int *motv, const char *data);
20 static int parse_keystate(unsigned int *st, const char *data);
23 static int devfd = -1;
26 static device_event evq[16];
27 static int evq_widx, evq_ridx;
28 #define QNEXT(x) (((x) + 1) & 0xf)
29 #define QEMPTY(b) (b##_ridx == b##_widx)
32 struct device *device_magellan(void)
34 static struct device dev = {
54 static void destroy(void)
58 static int opendev(const char *dev)
63 if((fd = ser_open(dev, 9600, SER_8N2 | SER_HWFLOW)) == -1) {
67 /* try for about 5 sec */
70 ser_printf(fd, "z\r");
71 } while(!ser_wait(fd, 250) && (timeout -= 250) > 0);
74 fprintf(stderr, "magellan open(%s): device does not respond\n", dev);
76 return -1; /* failed to get a response */
79 while(ser_getline(fd, buf, sizeof buf)) {
80 printf("magellan open(%s): %s\n", dev, buf);
83 ser_printf(fd, "vQ\r");
86 while(ser_getline(fd, buf, sizeof buf)) {
91 printf("magellan open(%s): got version string: \"%s\"\n", dev, buf + 1);
92 if(!strstr(buf, "v Magellan")) {
93 fprintf(stderr, "unknown device\n");
100 static int detect(void)
103 if((fd = opendev(get_port())) >= 0) {
110 static int start(void)
113 fprintf(stderr, "magellan start: already started\n");
117 if((devfd = opendev(get_port())) < 0) {
120 ser_printf(devfd, "m3\r"); /* start motion packets */
125 static void stop(void)
128 fprintf(stderr, "magellan stop: not started\n");
136 static int pending(void)
138 if(devfd < 0) return 0;
139 return ser_pending(devfd);
142 static int getevent(device_event *ev)
148 evq_ridx = QNEXT(evq_ridx);
154 static int proc_packets(void)
159 unsigned int st, delta, prev;
161 if(devfd < 0) return -1;
163 while(ser_getline(devfd, buf, sizeof buf)) {
168 if(parse_motion(ev->motion.motion, buf + 1) == -1) {
171 ev->type = DEV_EV_MOTION;
177 if(parse_keystate(&st, buf + 1) == -1) {
181 delta = st ^ bnstate;
185 for(i=0; i<32; i++) {
188 ev->type = DEV_EV_BUTTON;
190 ev->button.pressed = st & 1;
191 ev->button.state = prev ^ (1 << i);
203 static void enqueue_event(device_event *ev)
205 if(ev != evq + evq_widx) {
209 evq_widx = QNEXT(evq_widx);
210 if(evq_widx == evq_ridx) {
211 /* overflowed, drop the oldest event */
212 evq_ridx = QNEXT(evq_ridx);
216 static int parse_motion(int *motv, const char *data)
222 if(!data[0] || !data[1] || !data[2] || !data[3]) {
225 val = ((((long)data[0] & 0xf) << 12) |
226 (((long)data[1] & 0xf) << 8) |
227 (((long)data[2] & 0xf) << 4) |
228 ((long)data[3] & 0xf)) - 32768;
235 static int parse_keystate(unsigned int *stptr, const char *data)
242 st |= ((unsigned int)*data++ & 0xf) << bit;