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 ser_printf(fd, "vQ\r");
81 while(ser_getline_block(fd, buf, sizeof buf) && buf[0] != 'v');
83 printf("DBG: \"%s\"\n", buf);
84 if(buf[0] != 'v' || !strstr(buf, "MAGELLAN")) {
85 fprintf(stderr, "unknown device: \"%s\"\n", buf + 1);
92 static int detect(void)
95 if((fd = opendev(get_port())) >= 0) {
102 static int start(void)
105 fprintf(stderr, "magellan start: already started\n");
109 if((devfd = opendev(get_port())) < 0) {
112 ser_printf(devfd, "m3\r"); /* start motion packets */
117 static void stop(void)
120 fprintf(stderr, "magellan stop: not started\n");
128 static int pending(void)
130 if(devfd < 0) return 0;
131 return ser_pending(devfd);
134 static int getevent(device_event *ev)
140 evq_ridx = QNEXT(evq_ridx);
146 static int proc_packets(void)
151 unsigned int st, delta, prev;
153 if(devfd < 0) return -1;
155 while(ser_getline(devfd, buf, sizeof buf)) {
160 if(parse_motion(ev->motion.motion, buf + 1) == -1) {
163 ev->type = DEV_EV_MOTION;
169 if(parse_keystate(&st, buf + 1) == -1) {
173 delta = st ^ bnstate;
177 for(i=0; i<32; i++) {
180 ev->type = DEV_EV_BUTTON;
182 ev->button.pressed = st & 1;
183 ev->button.state = prev ^ (1 << i);
195 static void enqueue_event(device_event *ev)
197 if(ev != evq + evq_widx) {
201 evq_widx = QNEXT(evq_widx);
202 if(evq_widx == evq_ridx) {
203 /* overflowed, drop the oldest event */
204 evq_ridx = QNEXT(evq_ridx);
208 static int parse_motion(int *motv, const char *data)
214 if(!data[0] || !data[1] || !data[2] || !data[3]) {
217 val = ((((long)data[0] & 0xf) << 12) |
218 (((long)data[1] & 0xf) << 8) |
219 (((long)data[2] & 0xf) << 4) |
220 ((long)data[3] & 0xf)) - 32768;
227 static int parse_keystate(unsigned int *stptr, const char *data)
234 st |= ((unsigned int)*data++ & 0xf) << bit;