mse.c

来自「基于组件方式开发操作系统的OSKIT源代码」· C语言 代码 · 共 789 行 · 第 1/2 页

C
789
字号
	sc->sc_bytesread += xfer;	return(0);}/* * mseioctl: process ioctl commands. */static intmseioctl(dev, cmd, addr, flag, p)	dev_t dev;	u_long cmd;	caddr_t addr;	int flag;	struct proc *p;{	register struct mse_softc *sc = &mse_sc[MSE_UNIT(dev)];	mousestatus_t status;	int err = 0;	int s;	switch (cmd) {	case MOUSE_GETHWINFO:		s = spltty();		*(mousehw_t *)addr = sc->hw;		if (sc->mode.level == 0)			((mousehw_t *)addr)->model = MOUSE_MODEL_GENERIC;		splx(s);		break;	case MOUSE_GETMODE:		s = spltty();		*(mousemode_t *)addr = sc->mode;		switch (sc->mode.level) {		case 0:			break;		case 1:			((mousemode_t *)addr)->protocol = MOUSE_PROTO_SYSMOUSE;	    		((mousemode_t *)addr)->syncmask[0] = MOUSE_SYS_SYNCMASK;	    		((mousemode_t *)addr)->syncmask[1] = MOUSE_SYS_SYNC;			break;		}		splx(s);		break;	case MOUSE_SETMODE:		switch (((mousemode_t *)addr)->level) {		case 0:		case 1:			break;		default:			return (EINVAL);		}		if (((mousemode_t *)addr)->accelfactor < -1)			return (EINVAL);		else if (((mousemode_t *)addr)->accelfactor >= 0)			sc->mode.accelfactor = 			    ((mousemode_t *)addr)->accelfactor;		sc->mode.level = ((mousemode_t *)addr)->level;		switch (sc->mode.level) {		case 0:			sc->sc_bytesread = sc->mode.packetsize 			    = MOUSE_MSC_PACKETSIZE;			break;		case 1:			sc->sc_bytesread = sc->mode.packetsize 			    = MOUSE_SYS_PACKETSIZE;			break;		}		break;	case MOUSE_GETLEVEL:		*(int *)addr = sc->mode.level;		break;	case MOUSE_SETLEVEL:		switch (*(int *)addr) {		case 0:			sc->mode.level = *(int *)addr;			sc->sc_bytesread = sc->mode.packetsize 			    = MOUSE_MSC_PACKETSIZE;			break;		case 1:			sc->mode.level = *(int *)addr;			sc->sc_bytesread = sc->mode.packetsize 			    = MOUSE_SYS_PACKETSIZE;			break;		default:			return (EINVAL);		}		break;	case MOUSE_GETSTATUS:		s = spltty();		status = sc->status;		sc->status.flags = 0;		sc->status.obutton = sc->status.button;		sc->status.button = 0;		sc->status.dx = 0;		sc->status.dy = 0;		sc->status.dz = 0;		splx(s);		*(mousestatus_t *)addr = status;		break;	case MOUSE_READSTATE:	case MOUSE_READDATA:		return (ENODEV);#if (defined(MOUSE_GETVARS))	case MOUSE_GETVARS:	case MOUSE_SETVARS:		return (ENODEV);#endif	default:		return (ENOTTY);	}	return (err);}/* * msepoll: check for mouse input to be processed. */static	intmsepoll(dev, events, p)	dev_t dev;	int events;	struct proc *p;{	register struct mse_softc *sc = &mse_sc[MSE_UNIT(dev)];	int s;	int revents = 0;	s = spltty();	if (events & (POLLIN | POLLRDNORM))		if (sc->sc_bytesread != sc->mode.packetsize ||		    sc->sc_deltax != 0 || sc->sc_deltay != 0 ||		    (sc->sc_obuttons ^ sc->sc_buttons) != 0)			revents |= events & (POLLIN | POLLRDNORM);		else {			/*			 * Since this is an exclusive open device, any previous			 * proc pointer is trash now, so we can just assign it.			 */			selrecord(p, &sc->sc_selp);		}	splx(s);	return (revents);}/* * mseintr: update mouse status. sc_deltax and sc_deltay are accumulative. */static voidmseintr(unit)	int unit;{	/*	 * the table to turn MouseSystem button bits (MOUSE_MSC_BUTTON?UP)	 * into `mousestatus' button bits (MOUSE_BUTTON?DOWN).	 */	static int butmap[8] = {		0, 		MOUSE_BUTTON3DOWN, 		MOUSE_BUTTON2DOWN, 		MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN, 		MOUSE_BUTTON1DOWN, 		MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN, 		MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN,        	MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN	};	register struct mse_softc *sc = &mse_sc[unit];	int dx, dy, but;	int sign;#ifdef DEBUG	static int mse_intrcnt = 0;	if((mse_intrcnt++ % 10000) == 0)		printf("mseintr\n");#endif /* DEBUG */	if ((sc->sc_flags & MSESC_OPEN) == 0)		return;	(*sc->sc_getmouse)(sc->sc_port, &dx, &dy, &but);	if (sc->mode.accelfactor > 0) {		sign = (dx < 0);		dx = dx * dx / sc->mode.accelfactor;		if (dx == 0)			dx = 1;		if (sign)			dx = -dx;		sign = (dy < 0);		dy = dy * dy / sc->mode.accelfactor;		if (dy == 0)			dy = 1;		if (sign)			dy = -dy;	}	sc->sc_deltax += dx;	sc->sc_deltay += dy;	sc->sc_buttons = but;	but = butmap[~but & MOUSE_MSC_BUTTONS];	sc->status.dx += dx;	sc->status.dy += dy;	sc->status.flags |= ((dx || dy) ? MOUSE_POSCHANGED : 0)	    | (sc->status.button ^ but);	sc->status.button = but;	/*	 * If mouse state has changed, wake up anyone wanting to know.	 */	if (sc->sc_deltax != 0 || sc->sc_deltay != 0 ||	    (sc->sc_obuttons ^ sc->sc_buttons) != 0) {		if (sc->sc_flags & MSESC_WANT) {			sc->sc_flags &= ~MSESC_WANT;			wakeup((caddr_t)sc);		}		selwakeup(&sc->sc_selp);	}}/* * Routines for the Logitech mouse. *//* * Test for a Logitech bus mouse and return 1 if it is. * (until I know how to use the signature port properly, just disable *  interrupts and return 1) */static intmse_probelogi(idp)	register struct isa_device *idp;{	int sig;	outb(idp->id_iobase + MSE_PORTD, MSE_SETUP);		/* set the signature port */	outb(idp->id_iobase + MSE_PORTB, MSE_LOGI_SIG);	DELAY(30000); /* 30 ms delay */	sig = inb(idp->id_iobase + MSE_PORTB) & 0xFF;	if (sig == MSE_LOGI_SIG) {		outb(idp->id_iobase + MSE_PORTC, MSE_DISINTR);		return(1);	} else {		if (bootverbose)			printf("mse%d: wrong signature %x\n",idp->id_unit,sig);		return(0);	}}/* * Initialize Logitech mouse and enable interrupts. */static voidmse_enablelogi(port)	register u_int port;{	int dx, dy, but;	outb(port + MSE_PORTD, MSE_SETUP);	mse_getlogi(port, &dx, &dy, &but);}/* * Disable interrupts for Logitech mouse. */static voidmse_disablelogi(port)	register u_int port;{	outb(port + MSE_PORTC, MSE_DISINTR);}/* * Get the current dx, dy and button up/down state. */static voidmse_getlogi(port, dx, dy, but)	register u_int port;	int *dx;	int *dy;	int *but;{	register char x, y;	outb(port + MSE_PORTC, MSE_HOLD | MSE_RXLOW);	x = inb(port + MSE_PORTA);	*but = (x >> 5) & MOUSE_MSC_BUTTONS;	x &= 0xf;	outb(port + MSE_PORTC, MSE_HOLD | MSE_RXHIGH);	x |= (inb(port + MSE_PORTA) << 4);	outb(port + MSE_PORTC, MSE_HOLD | MSE_RYLOW);	y = (inb(port + MSE_PORTA) & 0xf);	outb(port + MSE_PORTC, MSE_HOLD | MSE_RYHIGH);	y |= (inb(port + MSE_PORTA) << 4);	*dx = x;	*dy = y;	outb(port + MSE_PORTC, MSE_INTREN);}/* * Routines for the ATI Inport bus mouse. *//* * Test for a ATI Inport bus mouse and return 1 if it is. * (do not enable interrupts) */static intmse_probeati(idp)	register struct isa_device *idp;{	int i;	for (i = 0; i < 2; i++)		if (inb(idp->id_iobase + MSE_PORTC) == 0xde)			return (1);	return (0);}/* * Initialize ATI Inport mouse and enable interrupts. */static voidmse_enableati(port)	register u_int port;{	outb(port + MSE_PORTA, MSE_INPORT_RESET);	outb(port + MSE_PORTA, MSE_INPORT_MODE);	outb(port + MSE_PORTB, MSE_INPORT_INTREN);}/* * Disable interrupts for ATI Inport mouse. */static voidmse_disableati(port)	register u_int port;{	outb(port + MSE_PORTA, MSE_INPORT_MODE);	outb(port + MSE_PORTB, 0);}/* * Get current dx, dy and up/down button state. */static voidmse_getati(port, dx, dy, but)	register u_int port;	int *dx;	int *dy;	int *but;{	register char byte;	outb(port + MSE_PORTA, MSE_INPORT_MODE);	outb(port + MSE_PORTB, MSE_INPORT_HOLD);	outb(port + MSE_PORTA, MSE_INPORT_STATUS);	*but = ~inb(port + MSE_PORTB) & MOUSE_MSC_BUTTONS;	outb(port + MSE_PORTA, MSE_INPORT_DX);	byte = inb(port + MSE_PORTB);	*dx = byte;	outb(port + MSE_PORTA, MSE_INPORT_DY);	byte = inb(port + MSE_PORTB);	*dy = byte;	outb(port + MSE_PORTA, MSE_INPORT_MODE);	outb(port + MSE_PORTB, MSE_INPORT_INTREN);}static mse_devsw_installed = 0;static void 	mse_drvinit(void *unused){	dev_t dev;	if( ! mse_devsw_installed ) {		dev = makedev(CDEV_MAJOR, 0);		cdevsw_add(&dev,&mse_cdevsw, NULL);		mse_devsw_installed = 1;    	}}SYSINIT(msedev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,mse_drvinit,NULL)#endif /* NMSE */

⌨️ 快捷键说明

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