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 */
81 ser_printf(fd, "vQ\r");
83 ser_getline(fd, buf, sizeof buf);
84 } while(buf[0] != 'v');
86 if(buf[0] != 'v' || !strstr(buf, "MAGELLAN")) {
87 fprintf(stderr, "unknown device: \"%s\"\n", buf + 1);
96 static int detect(void)
99 if((fd = opendev(get_port())) >= 0) {
106 static int start(void)
109 fprintf(stderr, "magellan start: already started\n");
113 if((devfd = opendev(get_port())) < 0) {
116 ser_printf(devfd, "m3\r"); /* start motion packets */
121 static void stop(void)
124 fprintf(stderr, "magellan stop: not started\n");
132 static int pending(void)
134 if(devfd < 0) return 0;
135 return ser_pending(devfd);
138 static int getevent(device_event *ev)
144 evq_ridx = QNEXT(evq_ridx);
150 static int proc_packets(void)
155 unsigned int st, delta, prev;
157 if(devfd < 0) return -1;
159 while(ser_getline(devfd, buf, sizeof buf)) {
164 if(parse_motion(ev->motion.motion, buf + 1) == -1) {
167 ev->type = DEV_EV_MOTION;
173 if(parse_keystate(&st, buf + 1) == -1) {
177 delta = st ^ bnstate;
181 for(i=0; i<32; i++) {
184 ev->type = DEV_EV_BUTTON;
186 ev->button.pressed = st & 1;
187 ev->button.state = prev ^ (1 << i);
199 static void enqueue_event(device_event *ev)
201 if(ev != evq + evq_widx) {
205 evq_widx = QNEXT(evq_widx);
206 if(evq_widx == evq_ridx) {
207 /* overflowed, drop the oldest event */
208 evq_ridx = QNEXT(evq_ridx);
212 static int parse_motion(int *motv, const char *data)
218 if(!data[0] || !data[1] || !data[2] || !data[3]) {
221 val = ((((long)data[0] & 0xf) << 12) |
222 (((long)data[1] & 0xf) << 8) |
223 (((long)data[2] & 0xf) << 4) |
224 ((long)data[3] & 0xf)) - 32768;
231 static int parse_keystate(unsigned int *stptr, const char *data)
238 st |= ((unsigned int)*data++ & 0xf) << bit;