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 + -
显示快捷键?