xref: /plan9/sys/src/cmd/aux/mouse.c (revision 39734e7ed1eb944f5e7b41936007d0d38b560d7f)
1bd389b36SDavid du Colombier #include <u.h>
2bd389b36SDavid du Colombier #include <libc.h>
3bd389b36SDavid du Colombier 
4bd389b36SDavid du Colombier enum
5bd389b36SDavid du Colombier {
6bd389b36SDavid du Colombier 	Sleep500	= 500,
7bd389b36SDavid du Colombier 	Sleep1000	= 1000,
8bd389b36SDavid du Colombier 	Sleep2000	= 2000,
9219b2ee8SDavid du Colombier 
10219b2ee8SDavid du Colombier 	TIMEOUT		= 5000,		/* timeout for writes */
11bd389b36SDavid du Colombier };
12bd389b36SDavid du Colombier 
13bd389b36SDavid du Colombier char *speeds[] =
14bd389b36SDavid du Colombier {
15bd389b36SDavid du Colombier 	"b1200",
16bd389b36SDavid du Colombier 	"b2400",
17bd389b36SDavid du Colombier 	"b4800",
18bd389b36SDavid du Colombier 	"b9600",
19bd389b36SDavid du Colombier 	0,
20bd389b36SDavid du Colombier };
21bd389b36SDavid du Colombier 
22219b2ee8SDavid du Colombier int	button2;
23219b2ee8SDavid du Colombier 
24bd389b36SDavid du Colombier #define DEBUG if(debug)
25bd389b36SDavid du Colombier 
26bd389b36SDavid du Colombier int can9600;	/* true if type W mouse can be set to 9600 */
27bd389b36SDavid du Colombier int debug;
28219b2ee8SDavid du Colombier int dontset;	/* true if we shouldn't try to set the mouse type */
29bd389b36SDavid du Colombier 
30bd389b36SDavid du Colombier static void
usage(void)31bd389b36SDavid du Colombier usage(void)
32bd389b36SDavid du Colombier {
33bd389b36SDavid du Colombier 	fprint(2, "%s: usage: %s [device]\n", argv0, argv0);
34bd389b36SDavid du Colombier 	exits("usage");
35bd389b36SDavid du Colombier }
36bd389b36SDavid du Colombier 
37bd389b36SDavid du Colombier static void
catch(void * a,char * msg)38bd389b36SDavid du Colombier catch(void *a, char *msg)
39bd389b36SDavid du Colombier {
40bd389b36SDavid du Colombier 	USED(a, msg);
41219b2ee8SDavid du Colombier 	if(strstr(msg, "alarm"))
42bd389b36SDavid du Colombier 		noted(NCONT);
43219b2ee8SDavid du Colombier 	noted(NDFLT);
44bd389b36SDavid du Colombier }
45bd389b36SDavid du Colombier 
46bd389b36SDavid du Colombier static void
dumpbuf(char * buf,int nbytes,char * s)47bd389b36SDavid du Colombier dumpbuf(char *buf, int nbytes, char *s)
48bd389b36SDavid du Colombier {
49bd389b36SDavid du Colombier 	print(s);
50219b2ee8SDavid du Colombier 	while(nbytes-- > 0)
51bd389b36SDavid du Colombier 		print("#%ux ", *buf++ & 0xFF);
52bd389b36SDavid du Colombier 	print("\n");
53bd389b36SDavid du Colombier }
54bd389b36SDavid du Colombier 
55219b2ee8SDavid du Colombier static long
timedwrite(int fd,void * p,int n)56219b2ee8SDavid du Colombier timedwrite(int fd, void *p, int n)
57219b2ee8SDavid du Colombier {
58219b2ee8SDavid du Colombier 	long rv;
59219b2ee8SDavid du Colombier 
60219b2ee8SDavid du Colombier 	alarm(TIMEOUT);
61219b2ee8SDavid du Colombier 	rv = write(fd, p, n);
62219b2ee8SDavid du Colombier 	alarm(0);
63219b2ee8SDavid du Colombier 	if(rv < 0){
64219b2ee8SDavid du Colombier 		fprint(2, "%s: timed out\n", argv0);
65219b2ee8SDavid du Colombier 		exits("timeout");
66219b2ee8SDavid du Colombier 	}
67219b2ee8SDavid du Colombier 	return rv;
68219b2ee8SDavid du Colombier }
69219b2ee8SDavid du Colombier 
70bd389b36SDavid du Colombier static int
readbyte(int fd)71bd389b36SDavid du Colombier readbyte(int fd)
72bd389b36SDavid du Colombier {
73bd389b36SDavid du Colombier 	uchar c;
749a747e4fSDavid du Colombier 	char buf[ERRMAX];
75bd389b36SDavid du Colombier 
76bd389b36SDavid du Colombier 	alarm(200);
77bd389b36SDavid du Colombier 	if(read(fd, &c, sizeof(c)) == -1){
78bd389b36SDavid du Colombier 		alarm(0);
799a747e4fSDavid du Colombier 		errstr(buf, sizeof buf);
80bd389b36SDavid du Colombier 		if(strcmp(buf, "interrupted") == 0)
81bd389b36SDavid du Colombier 			return -1;
82bd389b36SDavid du Colombier 		fprint(2, "%s: readbyte failed - %s\n", argv0, buf);
83bd389b36SDavid du Colombier 		exits("read");
84bd389b36SDavid du Colombier 	}
85bd389b36SDavid du Colombier 	alarm(0);
86bd389b36SDavid du Colombier 	return c;
87bd389b36SDavid du Colombier }
88bd389b36SDavid du Colombier 
89bd389b36SDavid du Colombier static int
slowread(int fd,char * buf,int nbytes,char * msg)90219b2ee8SDavid du Colombier slowread(int fd, char *buf, int nbytes, char *msg)
91bd389b36SDavid du Colombier {
92bd389b36SDavid du Colombier 	char *p;
93bd389b36SDavid du Colombier 	int c;
94bd389b36SDavid du Colombier 
95219b2ee8SDavid du Colombier 	for(p = buf; nbytes > 1 && (c = readbyte(fd)) != -1; *p++ = c, nbytes--)
96bd389b36SDavid du Colombier 		;
97bd389b36SDavid du Colombier 	*p = 0;
98219b2ee8SDavid du Colombier 	DEBUG dumpbuf(buf, p-buf, msg);
99bd389b36SDavid du Colombier 	return p-buf;
100bd389b36SDavid du Colombier }
101bd389b36SDavid du Colombier 
102bd389b36SDavid du Colombier static void
toggleRTS(int fd)103bd389b36SDavid du Colombier toggleRTS(int fd)
104bd389b36SDavid du Colombier {
105bd389b36SDavid du Colombier 	/*
106bd389b36SDavid du Colombier 	 *
107bd389b36SDavid du Colombier 	 * reset the mouse (toggle RTS)
108bd389b36SDavid du Colombier 	 * must be >100mS
109bd389b36SDavid du Colombier 	 */
1107dd7cddfSDavid du Colombier 	timedwrite(fd, "d1", 2);
1117dd7cddfSDavid du Colombier 	timedwrite(fd, "r1", 2);
1127dd7cddfSDavid du Colombier 	sleep(Sleep500);
113219b2ee8SDavid du Colombier 	timedwrite(fd, "d0", 2);
114219b2ee8SDavid du Colombier 	timedwrite(fd, "r0", 2);
115bd389b36SDavid du Colombier 	sleep(Sleep500);
116219b2ee8SDavid du Colombier 	timedwrite(fd, "d1", 2);
117219b2ee8SDavid du Colombier 	timedwrite(fd, "r1", 2);
118bd389b36SDavid du Colombier 	sleep(Sleep500);
119bd389b36SDavid du Colombier }
120bd389b36SDavid du Colombier 
121bd389b36SDavid du Colombier static void
setupeia(int fd,char * baud,char * bits)122bd389b36SDavid du Colombier setupeia(int fd, char *baud, char *bits)
123bd389b36SDavid du Colombier {
124219b2ee8SDavid du Colombier 	alarm(TIMEOUT);
125bd389b36SDavid du Colombier 	/*
126bd389b36SDavid du Colombier 	 * set the speed to 1200/2400/4800/9600 baud,
127bd389b36SDavid du Colombier 	 * 7/8-bit data, one stop bit and no parity
128bd389b36SDavid du Colombier 	 */
129bd389b36SDavid du Colombier 	DEBUG print("setupeia(%s,%s)\n", baud, bits);
130219b2ee8SDavid du Colombier 	timedwrite(fd, baud, strlen(baud));
131219b2ee8SDavid du Colombier 	timedwrite(fd, bits, strlen(bits));
132219b2ee8SDavid du Colombier 	timedwrite(fd, "s1", 2);
133219b2ee8SDavid du Colombier 	timedwrite(fd, "pn", 2);
134*39734e7eSDavid du Colombier 	timedwrite(fd, "i1", 2);
135219b2ee8SDavid du Colombier 	alarm(0);
136bd389b36SDavid du Colombier }
137bd389b36SDavid du Colombier 
138bd389b36SDavid du Colombier /*
139bd389b36SDavid du Colombier  *  check for a types M, M3, & W
140bd389b36SDavid du Colombier  *
141bd389b36SDavid du Colombier  *  we talk to all these mice using 1200 baud
142bd389b36SDavid du Colombier  */
143bd389b36SDavid du Colombier int
MorW(int ctl,int data)144bd389b36SDavid du Colombier MorW(int ctl, int data)
145bd389b36SDavid du Colombier {
146bd389b36SDavid du Colombier 	char buf[256];
147bd389b36SDavid du Colombier 	int c;
148bd389b36SDavid du Colombier 
149bd389b36SDavid du Colombier 	/*
150bd389b36SDavid du Colombier 	 * set up for type M, V or W
151bd389b36SDavid du Colombier 	 * flush any pending data
152bd389b36SDavid du Colombier 	 */
153bd389b36SDavid du Colombier 	setupeia(ctl, "b1200", "l7");
154bd389b36SDavid du Colombier 	toggleRTS(ctl);
155219b2ee8SDavid du Colombier 	while(slowread(data, buf, sizeof(buf), "flush: ") > 0)
156219b2ee8SDavid du Colombier 		;
157bd389b36SDavid du Colombier 	toggleRTS(ctl);
158bd389b36SDavid du Colombier 
159bd389b36SDavid du Colombier 	/*
160bd389b36SDavid du Colombier 	 * see if there's any data from the mouse
161bd389b36SDavid du Colombier 	 * (type M, V and W mice)
162bd389b36SDavid du Colombier 	 */
163219b2ee8SDavid du Colombier 	c = slowread(data, buf, sizeof(buf), "check M: ");
164bd389b36SDavid du Colombier 
165bd389b36SDavid du Colombier 	/*
166bd389b36SDavid du Colombier 	 * type M, V and W mice return "M" or "M3" after reset.
167bd389b36SDavid du Colombier 	 * check for type W by sending a 'Send Standard Configuration'
168bd389b36SDavid du Colombier 	 * command, "*?".
169219b2ee8SDavid du Colombier 	 *
170219b2ee8SDavid du Colombier 	 * the second check is a kludge for some type W mice on next's
171219b2ee8SDavid du Colombier 	 * that send a garbage character back before the "M3".
172bd389b36SDavid du Colombier 	 */
173219b2ee8SDavid du Colombier 	if((c > 0 && buf[0] == 'M') || (c > 1 && buf[1] == 'M')){
174219b2ee8SDavid du Colombier 		timedwrite(data, "*?", 2);
175219b2ee8SDavid du Colombier 		c = slowread(data, buf, sizeof(buf), "check W: ");
176bd389b36SDavid du Colombier 		/*
177bd389b36SDavid du Colombier 		 * 4 bytes back
178bd389b36SDavid du Colombier 		 * indicates a type W mouse
179bd389b36SDavid du Colombier 		 */
180219b2ee8SDavid du Colombier 		if(c == 4){
181bd389b36SDavid du Colombier 			if(buf[1] & (1<<4))
182bd389b36SDavid du Colombier 				can9600 = 1;
183bd389b36SDavid du Colombier 			setupeia(ctl, "b1200", "l8");
184219b2ee8SDavid du Colombier 			timedwrite(data, "*U", 2);
185219b2ee8SDavid du Colombier 			slowread(data, buf, sizeof(buf), "check W: ");
186bd389b36SDavid du Colombier 			return 'W';
187bd389b36SDavid du Colombier 		}
188bd389b36SDavid du Colombier 		return 'M';
189bd389b36SDavid du Colombier 	}
190bd389b36SDavid du Colombier 	return 0;
191bd389b36SDavid du Colombier }
192bd389b36SDavid du Colombier 
193bd389b36SDavid du Colombier /*
194bd389b36SDavid du Colombier  *  check for type C by seeing if it responds to the status
195bd389b36SDavid du Colombier  *  command "s".  the mouse is at an unknown speed so we
196bd389b36SDavid du Colombier  *  have to check all possible speeds.
197bd389b36SDavid du Colombier  */
198bd389b36SDavid du Colombier int
C(int ctl,int data)199bd389b36SDavid du Colombier C(int ctl, int data)
200bd389b36SDavid du Colombier {
201bd389b36SDavid du Colombier 	char **s;
202bd389b36SDavid du Colombier 	int c;
203bd389b36SDavid du Colombier 	char buf[256];
204bd389b36SDavid du Colombier 
205bd389b36SDavid du Colombier 	sleep(100);
206bd389b36SDavid du Colombier 	for(s = speeds; *s; s++){
207bd389b36SDavid du Colombier 		DEBUG print("%s\n", *s);
208bd389b36SDavid du Colombier 		setupeia(ctl, *s, "l8");
209219b2ee8SDavid du Colombier 		timedwrite(data, "s", 1);
210219b2ee8SDavid du Colombier 		c = slowread(data, buf, sizeof(buf), "check C: ");
211bd389b36SDavid du Colombier 		if(c >= 1 && (*buf & 0xBF) == 0x0F){
212bd389b36SDavid du Colombier 			sleep(100);
213219b2ee8SDavid du Colombier 			timedwrite(data, "*n", 2);
214bd389b36SDavid du Colombier 			sleep(100);
215bd389b36SDavid du Colombier 			setupeia(ctl, "b1200", "l8");
216219b2ee8SDavid du Colombier 			timedwrite(data, "s", 1);
217219b2ee8SDavid du Colombier 			c = slowread(data, buf, sizeof(buf), "recheck C: ");
218bd389b36SDavid du Colombier 			if(c >= 1 && (*buf & 0xBF) == 0x0F){
219219b2ee8SDavid du Colombier 				timedwrite(data, "U", 1);
220bd389b36SDavid du Colombier 				return 'C';
221bd389b36SDavid du Colombier 			}
222bd389b36SDavid du Colombier 		}
223bd389b36SDavid du Colombier 		sleep(100);
224bd389b36SDavid du Colombier 	}
225bd389b36SDavid du Colombier 
226bd389b36SDavid du Colombier 	return 0;
227bd389b36SDavid du Colombier }
228bd389b36SDavid du Colombier 
229bd389b36SDavid du Colombier char *bauderr = "mouse: can't set baud rate, mouse at 1200\n";
230bd389b36SDavid du Colombier 
231bd389b36SDavid du Colombier void
Cbaud(int ctl,int data,int baud)232bd389b36SDavid du Colombier Cbaud(int ctl, int data, int baud)
233bd389b36SDavid du Colombier {
234bd389b36SDavid du Colombier 	char buf[32];
235bd389b36SDavid du Colombier 
236bd389b36SDavid du Colombier 	switch(baud){
237bd389b36SDavid du Colombier 	case 0:
238bd389b36SDavid du Colombier 	case 1200:
239bd389b36SDavid du Colombier 		return;
240bd389b36SDavid du Colombier 	case 2400:
241bd389b36SDavid du Colombier 		buf[1] = 'o';
242bd389b36SDavid du Colombier 		break;
243bd389b36SDavid du Colombier 	case 4800:
244bd389b36SDavid du Colombier 		buf[1] = 'p';
245bd389b36SDavid du Colombier 		break;
246bd389b36SDavid du Colombier 	case 9600:
247bd389b36SDavid du Colombier 		buf[1] = 'q';
248bd389b36SDavid du Colombier 		break;
249bd389b36SDavid du Colombier 	default:
250bd389b36SDavid du Colombier 		fprint(2, bauderr);
251bd389b36SDavid du Colombier 		return;
252bd389b36SDavid du Colombier 	}
253bd389b36SDavid du Colombier 
254bd389b36SDavid du Colombier 	buf[0] = '*';
255bd389b36SDavid du Colombier 	buf[2] = 0;
256bd389b36SDavid du Colombier 	sleep(100);
257219b2ee8SDavid du Colombier 	timedwrite(data, buf, 2);
258bd389b36SDavid du Colombier 	sleep(100);
259219b2ee8SDavid du Colombier 	timedwrite(data, buf, 2);
260bd389b36SDavid du Colombier 	sprint(buf, "b%d", baud);
261bd389b36SDavid du Colombier 	setupeia(ctl, buf, "l8");
262bd389b36SDavid du Colombier }
263bd389b36SDavid du Colombier 
264bd389b36SDavid du Colombier void
Wbaud(int ctl,int data,int baud)265bd389b36SDavid du Colombier Wbaud(int ctl, int data, int baud)
266bd389b36SDavid du Colombier {
267bd389b36SDavid du Colombier 	char buf[32];
268bd389b36SDavid du Colombier 
269bd389b36SDavid du Colombier 	switch(baud){
270bd389b36SDavid du Colombier 	case 0:
271bd389b36SDavid du Colombier 	case 1200:
272bd389b36SDavid du Colombier 		return;
273bd389b36SDavid du Colombier 	case 9600:
274bd389b36SDavid du Colombier 		if(can9600)
275bd389b36SDavid du Colombier 			break;
276bd389b36SDavid du Colombier 		/* fall through */
277bd389b36SDavid du Colombier 	default:
278bd389b36SDavid du Colombier 		fprint(2, bauderr);
279bd389b36SDavid du Colombier 		return;
280bd389b36SDavid du Colombier 	}
281219b2ee8SDavid du Colombier 	timedwrite(data, "*q", 2);
282bd389b36SDavid du Colombier 	setupeia(ctl, "b9600", "l8");
283219b2ee8SDavid du Colombier 	slowread(data, buf, sizeof(buf), "setbaud: ");
284219b2ee8SDavid du Colombier }
285219b2ee8SDavid du Colombier 
286bd389b36SDavid du Colombier void
main(int argc,char * argv[])287bd389b36SDavid du Colombier main(int argc, char *argv[])
288bd389b36SDavid du Colombier {
289bd389b36SDavid du Colombier 	char *p;
290bd389b36SDavid du Colombier 	int baud;
2917dd7cddfSDavid du Colombier 	int tries, conf, ctl, data, def, type;
292bd389b36SDavid du Colombier 	char buf[256];
293bd389b36SDavid du Colombier 
294bd389b36SDavid du Colombier 	def = 0;
295bd389b36SDavid du Colombier 	baud = 0;
296bd389b36SDavid du Colombier 	ARGBEGIN{
297bd389b36SDavid du Colombier 	case 'b':
298bd389b36SDavid du Colombier 		baud = atoi(ARGF());
299bd389b36SDavid du Colombier 		break;
300bd389b36SDavid du Colombier 	case 'd':
301bd389b36SDavid du Colombier 		p = ARGF();
302bd389b36SDavid du Colombier 		def = *p;
303bd389b36SDavid du Colombier 		break;
304219b2ee8SDavid du Colombier 	case 'n':
305219b2ee8SDavid du Colombier 		dontset = 1;
306219b2ee8SDavid du Colombier 		break;
307bd389b36SDavid du Colombier 	case 'D':
308bd389b36SDavid du Colombier 		debug = 1;
309bd389b36SDavid du Colombier 		break;
310bd389b36SDavid du Colombier 	default:
311bd389b36SDavid du Colombier 		usage();
312bd389b36SDavid du Colombier 	}ARGEND
313bd389b36SDavid du Colombier 
314bd389b36SDavid du Colombier 	p = "0";
315bd389b36SDavid du Colombier 	if(argc)
316bd389b36SDavid du Colombier 		p = *argv;
317bd389b36SDavid du Colombier 
3187dd7cddfSDavid du Colombier 	if((conf = open("/dev/mousectl", OWRITE)) == -1){
3197dd7cddfSDavid du Colombier 		fprint(2, "%s: can't open /dev/mousectl - %r\n", argv0);
320219b2ee8SDavid du Colombier 		if(dontset == 0)
3217dd7cddfSDavid du Colombier 			exits("open /dev/mousectl");
322bd389b36SDavid du Colombier 	}
323bd389b36SDavid du Colombier 
3247dd7cddfSDavid du Colombier 	if(strncmp(p, "ps2", 3) == 0){
3257dd7cddfSDavid du Colombier 		if(write(conf, p, strlen(p)) < 0){
326bd389b36SDavid du Colombier 			fprint(2, "%s: error setting mouse type - %r\n", argv0);
327bd389b36SDavid du Colombier 			exits("write conf");
328bd389b36SDavid du Colombier 		}
329bd389b36SDavid du Colombier 		exits(0);
330bd389b36SDavid du Colombier 	}
331bd389b36SDavid du Colombier 
3327dd7cddfSDavid du Colombier 	type = 0;
3337dd7cddfSDavid du Colombier 	for(tries = 0; type == 0 && tries < 6; tries++){
3347dd7cddfSDavid du Colombier 		if(tries)
3357dd7cddfSDavid du Colombier 			fprint(2, "%s: Unknown mouse type, retrying...\n", argv0);
336bd389b36SDavid du Colombier 		sprint(buf, "#t/eia%sctl", p);
337bd389b36SDavid du Colombier 		if((ctl = open(buf, ORDWR)) == -1){
338bd389b36SDavid du Colombier 			fprint(2, "%s: can't open %s - %r\n", argv0, buf);
339bd389b36SDavid du Colombier 			exits("open ctl");
340bd389b36SDavid du Colombier 		}
341bd389b36SDavid du Colombier 		sprint(buf, "#t/eia%s", p);
342bd389b36SDavid du Colombier 		if((data = open(buf, ORDWR)) == -1){
343bd389b36SDavid du Colombier 			fprint(2, "%s: can't open %s - %r\n", argv0, buf);
344bd389b36SDavid du Colombier 			exits("open data");
345bd389b36SDavid du Colombier 		}
346bd389b36SDavid du Colombier 
347bd389b36SDavid du Colombier 		notify(catch);
348bd389b36SDavid du Colombier 
349bd389b36SDavid du Colombier 		type = MorW(ctl, data);
350bd389b36SDavid du Colombier 		if(type == 0)
351bd389b36SDavid du Colombier 			type = C(ctl, data);
352bd389b36SDavid du Colombier 		if(type == 0){
353219b2ee8SDavid du Colombier 			/* with the default we can't assume anything */
354219b2ee8SDavid du Colombier 			baud = 0;
355219b2ee8SDavid du Colombier 
356bd389b36SDavid du Colombier 			/* try the default */
357bd389b36SDavid du Colombier 			switch(def){
358bd389b36SDavid du Colombier 			case 'C':
359bd389b36SDavid du Colombier 				setupeia(ctl, "b1200", "l8");
360bd389b36SDavid du Colombier 				break;
361bd389b36SDavid du Colombier 			case 'M':
362bd389b36SDavid du Colombier 				setupeia(ctl, "b1200", "l7");
363bd389b36SDavid du Colombier 				break;
364bd389b36SDavid du Colombier 			}
365219b2ee8SDavid du Colombier 
366bd389b36SDavid du Colombier 			type = def;
367bd389b36SDavid du Colombier 		}
368bd389b36SDavid du Colombier 
369bd389b36SDavid du Colombier 		sprint(buf, "serial %s", p);
370bd389b36SDavid du Colombier 		switch(type){
371bd389b36SDavid du Colombier 		case 0:
3727dd7cddfSDavid du Colombier 			close(data);
3737dd7cddfSDavid du Colombier 			close(ctl);
3747dd7cddfSDavid du Colombier 			continue;
375bd389b36SDavid du Colombier 		case 'C':
376219b2ee8SDavid du Colombier 			DEBUG print("Logitech 5 byte mouse\n");
377bd389b36SDavid du Colombier 			Cbaud(ctl, data, baud);
378bd389b36SDavid du Colombier 			break;
379bd389b36SDavid du Colombier 		case 'W':
380219b2ee8SDavid du Colombier 			DEBUG print("Type W mouse\n");
381bd389b36SDavid du Colombier 			Wbaud(ctl, data, baud);
382bd389b36SDavid du Colombier 			break;
383bd389b36SDavid du Colombier 		case 'M':
384219b2ee8SDavid du Colombier 			DEBUG print("Microsoft compatible mouse\n");
385bd389b36SDavid du Colombier 			strcat(buf, " M");
386bd389b36SDavid du Colombier 			break;
387bd389b36SDavid du Colombier 		}
3887dd7cddfSDavid du Colombier 	}
3897dd7cddfSDavid du Colombier 
3907dd7cddfSDavid du Colombier 	if(type == 0){
3917dd7cddfSDavid du Colombier 		fprint(2, "%s: Unknown mouse type, giving up\n", argv0);
3927dd7cddfSDavid du Colombier 		exits("no mouse");
3937dd7cddfSDavid du Colombier 	}
3947dd7cddfSDavid du Colombier 
395bd389b36SDavid du Colombier 	DEBUG fprint(2, "mouse configured as '%s'\n", buf);
396219b2ee8SDavid du Colombier 	if(dontset == 0 && write(conf, buf, strlen(buf)) < 0){
397bd389b36SDavid du Colombier 		fprint(2, "%s: error setting mouse type - %r\n", argv0);
398bd389b36SDavid du Colombier 		exits("write conf");
399bd389b36SDavid du Colombier 	}
4007dd7cddfSDavid du Colombier 
401bd389b36SDavid du Colombier 	exits(0);
402bd389b36SDavid du Colombier }
403