⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mouse.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>enum{	Sleep500	= 500,	Sleep1000	= 1000,	Sleep2000	= 2000,	TIMEOUT		= 5000,		/* timeout for writes */};char *speeds[] ={	"b1200",	"b2400",	"b4800",	"b9600",	0,};int	button2; #define DEBUG if(debug)int can9600;	/* true if type W mouse can be set to 9600 */int debug;int dontset;	/* true if we shouldn't try to set the mouse type */static voidusage(void){	fprint(2, "%s: usage: %s [device]\n", argv0, argv0);	exits("usage");}static voidcatch(void *a, char *msg){	USED(a, msg);	if(strstr(msg, "alarm"))		noted(NCONT);	noted(NDFLT);}static voiddumpbuf(char *buf, int nbytes, char *s){	print(s);	while(nbytes-- > 0)		print("#%ux ", *buf++ & 0xFF);	print("\n");}static longtimedwrite(int fd, void *p, int n){	long rv;	alarm(TIMEOUT);	rv = write(fd, p, n);	alarm(0);	if(rv < 0){		fprint(2, "%s: timed out\n", argv0);		exits("timeout");	}	return rv;}static intreadbyte(int fd){	uchar c;	char buf[ERRMAX];	alarm(200);	if(read(fd, &c, sizeof(c)) == -1){		alarm(0);		errstr(buf, sizeof buf);		if(strcmp(buf, "interrupted") == 0)			return -1;		fprint(2, "%s: readbyte failed - %s\n", argv0, buf);		exits("read");	}	alarm(0);	return c;}static intslowread(int fd, char *buf, int nbytes, char *msg){	char *p;	int c;	for(p = buf; nbytes > 1 && (c = readbyte(fd)) != -1; *p++ = c, nbytes--)		;	*p = 0;	DEBUG dumpbuf(buf, p-buf, msg);	return p-buf;}static voidtoggleRTS(int fd){	/*	 *	 * reset the mouse (toggle RTS)	 * must be >100mS	 */	timedwrite(fd, "d1", 2);	timedwrite(fd, "r1", 2);	sleep(Sleep500);	timedwrite(fd, "d0", 2);	timedwrite(fd, "r0", 2);	sleep(Sleep500);	timedwrite(fd, "d1", 2);	timedwrite(fd, "r1", 2);	sleep(Sleep500);}static voidsetupeia(int fd, char *baud, char *bits){	alarm(TIMEOUT);	/*	 * set the speed to 1200/2400/4800/9600 baud,	 * 7/8-bit data, one stop bit and no parity	 */	DEBUG print("setupeia(%s,%s)\n", baud, bits);	timedwrite(fd, baud, strlen(baud));	timedwrite(fd, bits, strlen(bits));	timedwrite(fd, "s1", 2);	timedwrite(fd, "pn", 2);	timedwrite(fd, "i1", 2);	alarm(0);}/* *  check for a types M, M3, & W * *  we talk to all these mice using 1200 baud */intMorW(int ctl, int data){	char buf[256];	int c;	/*	 * set up for type M, V or W	 * flush any pending data	 */	setupeia(ctl, "b1200", "l7");	toggleRTS(ctl);	while(slowread(data, buf, sizeof(buf), "flush: ") > 0)		;	toggleRTS(ctl);	/*	 * see if there's any data from the mouse	 * (type M, V and W mice)	 */	c = slowread(data, buf, sizeof(buf), "check M: ");	/*	 * type M, V and W mice return "M" or "M3" after reset.	 * check for type W by sending a 'Send Standard Configuration'	 * command, "*?".	 *	 * the second check is a kludge for some type W mice on next's	 * that send a garbage character back before the "M3".	 */	if((c > 0 && buf[0] == 'M') || (c > 1 && buf[1] == 'M')){		timedwrite(data, "*?", 2);		c = slowread(data, buf, sizeof(buf), "check W: ");		/*		 * 4 bytes back		 * indicates a type W mouse		 */		if(c == 4){			if(buf[1] & (1<<4))				can9600 = 1;			setupeia(ctl, "b1200", "l8");			timedwrite(data, "*U", 2);			slowread(data, buf, sizeof(buf), "check W: ");			return 'W';		}		return 'M';	}	return 0;}/* *  check for type C by seeing if it responds to the status *  command "s".  the mouse is at an unknown speed so we *  have to check all possible speeds. */intC(int ctl, int data){	char **s;	int c;	char buf[256];		sleep(100);	for(s = speeds; *s; s++){		DEBUG print("%s\n", *s);		setupeia(ctl, *s, "l8");		timedwrite(data, "s", 1);		c = slowread(data, buf, sizeof(buf), "check C: ");		if(c >= 1 && (*buf & 0xBF) == 0x0F){			sleep(100);			timedwrite(data, "*n", 2);			sleep(100);			setupeia(ctl, "b1200", "l8");			timedwrite(data, "s", 1);			c = slowread(data, buf, sizeof(buf), "recheck C: ");			if(c >= 1 && (*buf & 0xBF) == 0x0F){				timedwrite(data, "U", 1);				return 'C';			}		}		sleep(100);	}	return 0;}char *bauderr = "mouse: can't set baud rate, mouse at 1200\n";voidCbaud(int ctl, int data, int baud){	char buf[32];	switch(baud){	case 0:	case 1200:		return;	case 2400:		buf[1] = 'o';		break;	case 4800:		buf[1] = 'p';		break;	case 9600:		buf[1] = 'q';		break;	default:		fprint(2, bauderr);		return;	}	buf[0] = '*';	buf[2] = 0;	sleep(100);	timedwrite(data, buf, 2);	sleep(100);	timedwrite(data, buf, 2);	sprint(buf, "b%d", baud);	setupeia(ctl, buf, "l8");}voidWbaud(int ctl, int data, int baud){	char buf[32];	switch(baud){	case 0:	case 1200:		return;	case 9600:		if(can9600)			break;		/* fall through */	default:		fprint(2, bauderr);		return;	}	timedwrite(data, "*q", 2);	setupeia(ctl, "b9600", "l8");	slowread(data, buf, sizeof(buf), "setbaud: ");}voidmain(int argc, char *argv[]){	char *p;	int baud;	int tries, conf, ctl, data, def, type;	char buf[256];	def = 0;	baud = 0;	ARGBEGIN{	case 'b':		baud = atoi(ARGF());		break;	case 'd':		p = ARGF();		def = *p;		break;	case 'n':		dontset = 1;		break;	case 'D':		debug = 1;		break;	default:		usage();	}ARGEND	p = "0";	if(argc)		p = *argv;	if((conf = open("/dev/mousectl", OWRITE)) == -1){		fprint(2, "%s: can't open /dev/mousectl - %r\n", argv0);		if(dontset == 0)			exits("open /dev/mousectl");	}	if(strncmp(p, "ps2", 3) == 0){		if(write(conf, p, strlen(p)) < 0){			fprint(2, "%s: error setting mouse type - %r\n", argv0);			exits("write conf");		}		exits(0);	}	type = 0;	for(tries = 0; type == 0 && tries < 6; tries++){		if(tries)			fprint(2, "%s: Unknown mouse type, retrying...\n", argv0);		sprint(buf, "#t/eia%sctl", p);		if((ctl = open(buf, ORDWR)) == -1){			fprint(2, "%s: can't open %s - %r\n", argv0, buf);			exits("open ctl");		}		sprint(buf, "#t/eia%s", p);		if((data = open(buf, ORDWR)) == -1){			fprint(2, "%s: can't open %s - %r\n", argv0, buf);			exits("open data");		}			notify(catch);			type = MorW(ctl, data);		if(type == 0)			type = C(ctl, data);		if(type == 0){			/* with the default we can't assume anything */			baud = 0;				/* try the default */			switch(def){			case 'C':				setupeia(ctl, "b1200", "l8");				break;			case 'M':				setupeia(ctl, "b1200", "l7");				break;			}				type = def;		}			sprint(buf, "serial %s", p);		switch(type){		case 0:			close(data);			close(ctl);			continue;		case 'C':			DEBUG print("Logitech 5 byte mouse\n");			Cbaud(ctl, data, baud);			break;		case 'W':			DEBUG print("Type W mouse\n");			Wbaud(ctl, data, baud);			break;		case 'M':			DEBUG print("Microsoft compatible mouse\n");			strcat(buf, " M");			break;		}	}	if(type == 0){		fprint(2, "%s: Unknown mouse type, giving up\n", argv0);		exits("no mouse");	}	DEBUG fprint(2, "mouse configured as '%s'\n", buf);	if(dontset == 0 && write(conf, buf, strlen(buf)) < 0){		fprint(2, "%s: error setting mouse type - %r\n", argv0);		exits("write conf");	}	exits(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -