1139749Simp/*- 2138755Simp * Copyright (c) 2004 M. Warner Losh 3138755Simp * All rights reserved. 4138755Simp * 5138755Simp * Redistribution and use in source and binary forms, with or without 6138755Simp * modification, are permitted provided that the following conditions 7138755Simp * are met: 8138755Simp * 1. Redistributions of source code must retain the above copyright 9140040Simp * notice, this list of conditions and the following disclaimer. 10138755Simp * 2. Redistributions in binary form must reproduce the above copyright 11140040Simp * notice, this list of conditions and the following disclaimer in the 12140040Simp * documentation and/or other materials provided with the distribution. 13138755Simp * 14138755Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15138755Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16138755Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17140040Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18140040Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19138755Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20138755Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21138755Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22138755Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23138755Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24138755Simp * SUCH DAMAGE. 25138755Simp * 26138755Simp * $FreeBSD$ 27138755Simp */ 28138755Simp 29138755Simp/* 30637Snate * Copyright 1992 by the University of Guelph 31637Snate * 32637Snate * Permission to use, copy and modify this 33637Snate * software and its documentation for any purpose and without 34637Snate * fee is hereby granted, provided that the above copyright 35637Snate * notice appear in all copies and that both that copyright 36637Snate * notice and this permission notice appear in supporting 37637Snate * documentation. 38637Snate * University of Guelph makes no representations about the suitability of 39637Snate * this software for any purpose. It is provided "as is" 40637Snate * without express or implied warranty. 41637Snate */ 42637Snate/* 43637Snate * Driver for the Logitech and ATI Inport Bus mice for use with 386bsd and 44637Snate * the X386 port, courtesy of 45637Snate * Rick Macklem, rick@snowhite.cis.uoguelph.ca 46637Snate * Caveats: The driver currently uses spltty(), but doesn't use any 47637Snate * generic tty code. It could use splmse() (that only masks off the 48637Snate * bus mouse interrupt, but that would require hacking in i386/isa/icu.s. 49637Snate * (This may be worth the effort, since the Logitech generates 30/60 50637Snate * interrupts/sec continuously while it is open.) 51637Snate * NB: The ATI has NOT been tested yet! 52637Snate */ 53637Snate 54637Snate/* 55637Snate * Modification history: 564259Sjkh * Sep 6, 1994 -- Lars Fredriksen(fredriks@mcs.com) 574259Sjkh * improved probe based on input from Logitech. 58637Snate * 59637Snate * Oct 19, 1992 -- E. Stark (stark@cs.sunysb.edu) 60637Snate * fixes to make it work with Microsoft InPort busmouse 61637Snate * 62637Snate * Jan, 1993 -- E. Stark (stark@cs.sunysb.edu) 63637Snate * added patches for new "select" interface 64637Snate * 65637Snate * May 4, 1993 -- E. Stark (stark@cs.sunysb.edu) 66637Snate * changed position of some spl()'s in mseread 67637Snate * 68637Snate * October 8, 1993 -- E. Stark (stark@cs.sunysb.edu) 69637Snate * limit maximum negative x/y value to -127 to work around XFree problem 70637Snate * that causes spurious button pushes. 71637Snate */ 72637Snate 732056Swollman#include <sys/param.h> 743745Swollman#include <sys/systm.h> 7512658Sbde#include <sys/conf.h> 762056Swollman#include <sys/kernel.h> 77129882Sphk#include <sys/module.h> 7858229Syokota#include <sys/bus.h> 7929368Speter#include <sys/poll.h> 8071286Swollman#include <sys/selinfo.h> 812056Swollman#include <sys/uio.h> 8266860Sphk#include <sys/mouse.h> 83637Snate 8458229Syokota#include <machine/bus.h> 8558229Syokota#include <machine/resource.h> 8658229Syokota#include <sys/rman.h> 877430Sbde 8858229Syokota#include <isa/isavar.h> 89637Snate 90138755Simp#include <dev/mse/msevar.h> 9131603Syokota 92138755Simpdevclass_t mse_devclass; 93637Snate 9412675Sjulianstatic d_open_t mseopen; 9512675Sjulianstatic d_close_t mseclose; 9612675Sjulianstatic d_read_t mseread; 9731603Syokotastatic d_ioctl_t mseioctl; 9829368Speterstatic d_poll_t msepoll; 9912675Sjulian 10047625Sphkstatic struct cdevsw mse_cdevsw = { 101126080Sphk .d_version = D_VERSION, 102111815Sphk .d_open = mseopen, 103111815Sphk .d_close = mseclose, 104111815Sphk .d_read = mseread, 105111815Sphk .d_ioctl = mseioctl, 106111815Sphk .d_poll = msepoll, 107111815Sphk .d_name = "mse", 10847625Sphk}; 10912675Sjulian 11092765Salfredstatic void mseintr(void *); 111272956Sjhbstatic void mseintr_locked(mse_softc_t *sc); 112272956Sjhbstatic void msetimeout(void *); 11312675Sjulian 114272956Sjhb#define MSE_NBLOCKIO(dev) (dev2unit(dev) != 0) 115637Snate 116637Snate#define MSEPRI (PZERO + 3) 117637Snate 118138755Simpint 119138755Simpmse_common_attach(device_t dev) 120637Snate{ 12158229Syokota mse_softc_t *sc; 122138755Simp int unit, flags, rid; 123637Snate 12458229Syokota sc = device_get_softc(dev); 12558229Syokota unit = device_get_unit(dev); 126272956Sjhb mtx_init(&sc->sc_lock, "mse", NULL, MTX_DEF); 127272956Sjhb callout_init_mtx(&sc->sc_callout, &sc->sc_lock, 0); 12858229Syokota 12958229Syokota rid = 0; 130138755Simp sc->sc_intr = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 131138755Simp RF_ACTIVE); 13258229Syokota if (sc->sc_intr == NULL) { 13358229Syokota bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port); 134272956Sjhb mtx_destroy(&sc->sc_lock); 13558229Syokota return ENXIO; 13658229Syokota } 13758229Syokota 138272956Sjhb if (bus_setup_intr(dev, sc->sc_intr, INTR_TYPE_TTY | INTR_MPSAFE, 139272956Sjhb NULL, mseintr, sc, &sc->sc_ih)) { 14058229Syokota bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port); 14158229Syokota bus_release_resource(dev, SYS_RES_IRQ, rid, sc->sc_intr); 142272956Sjhb mtx_destroy(&sc->sc_lock); 14358229Syokota return ENXIO; 14458229Syokota } 14558229Syokota flags = device_get_flags(dev); 14658229Syokota sc->mode.accelfactor = (flags & MSE_CONFIG_ACCEL) >> 4; 14758229Syokota 148272956Sjhb sc->sc_dev = make_dev(&mse_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, 149272956Sjhb "mse%d", unit); 150191320Sed sc->sc_dev->si_drv1 = sc; 151272956Sjhb sc->sc_ndev = make_dev(&mse_cdevsw, 1, UID_ROOT, GID_WHEEL, 0600, 152272956Sjhb "nmse%d", unit); 153191320Sed sc->sc_ndev->si_drv1 = sc; 15458229Syokota return 0; 155637Snate} 156637Snate 157272956Sjhbint 158272956Sjhbmse_detach(device_t dev) 159272956Sjhb{ 160272956Sjhb mse_softc_t *sc; 161272956Sjhb int rid; 162272956Sjhb 163272956Sjhb sc = device_get_softc(dev); 164272956Sjhb MSE_LOCK(sc); 165272956Sjhb if (sc->sc_flags & MSESC_OPEN) { 166272956Sjhb MSE_UNLOCK(sc); 167272956Sjhb return EBUSY; 168272956Sjhb } 169272956Sjhb 170272956Sjhb /* Sabotage subsequent opens. */ 171272956Sjhb sc->sc_mousetype = MSE_NONE; 172272956Sjhb MSE_UNLOCK(sc); 173272956Sjhb 174272956Sjhb destroy_dev(sc->sc_dev); 175272956Sjhb destroy_dev(sc->sc_ndev); 176272956Sjhb 177272956Sjhb rid = 0; 178272956Sjhb bus_teardown_intr(dev, sc->sc_intr, sc->sc_ih); 179272956Sjhb bus_release_resource(dev, SYS_RES_IRQ, rid, sc->sc_intr); 180272956Sjhb bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port); 181272956Sjhb 182272956Sjhb callout_drain(&sc->sc_callout); 183272956Sjhb mtx_destroy(&sc->sc_lock); 184272956Sjhb 185272956Sjhb return 0; 186272956Sjhb} 187272956Sjhb 188637Snate/* 189637Snate * Exclusive open the mouse, initialize it and enable interrupts. 190637Snate */ 19112675Sjulianstatic int 192144783Simpmseopen(struct cdev *dev, int flags, int fmt, struct thread *td) 193637Snate{ 194191320Sed mse_softc_t *sc = dev->si_drv1; 195637Snate 196272956Sjhb MSE_LOCK(sc); 197272956Sjhb if (sc->sc_mousetype == MSE_NONE) { 198272956Sjhb MSE_UNLOCK(sc); 19920688Sjoerg return (ENXIO); 200272956Sjhb } 201272956Sjhb if (sc->sc_flags & MSESC_OPEN) { 202272956Sjhb MSE_UNLOCK(sc); 203637Snate return (EBUSY); 204272956Sjhb } 205637Snate sc->sc_flags |= MSESC_OPEN; 20631603Syokota sc->sc_obuttons = sc->sc_buttons = MOUSE_MSC_BUTTONS; 207637Snate sc->sc_deltax = sc->sc_deltay = 0; 20831603Syokota sc->sc_bytesread = sc->mode.packetsize = MOUSE_MSC_PACKETSIZE; 20958229Syokota sc->sc_watchdog = FALSE; 210272956Sjhb callout_reset(&sc->sc_callout, hz * 2, msetimeout, dev); 21131603Syokota sc->mode.level = 0; 21231603Syokota sc->status.flags = 0; 21331603Syokota sc->status.button = sc->status.obutton = 0; 21431603Syokota sc->status.dx = sc->status.dy = sc->status.dz = 0; 215637Snate 216637Snate /* 217637Snate * Initialize mouse interface and enable interrupts. 218637Snate */ 219272956Sjhb (*sc->sc_enablemouse)(sc->sc_port); 220272956Sjhb MSE_UNLOCK(sc); 221637Snate return (0); 222637Snate} 223637Snate 224637Snate/* 225637Snate * mseclose: just turn off mouse innterrupts. 226637Snate */ 22712675Sjulianstatic int 228144783Simpmseclose(struct cdev *dev, int flags, int fmt, struct thread *td) 229637Snate{ 230191320Sed mse_softc_t *sc = dev->si_drv1; 231637Snate 232272956Sjhb MSE_LOCK(sc); 233272956Sjhb callout_stop(&sc->sc_callout); 234272956Sjhb (*sc->sc_disablemouse)(sc->sc_port); 235637Snate sc->sc_flags &= ~MSESC_OPEN; 236272956Sjhb MSE_UNLOCK(sc); 237637Snate return(0); 238637Snate} 239637Snate 2408876Srgrimes/* 241637Snate * mseread: return mouse info using the MSC serial protocol, but without 242637Snate * using bytes 4 and 5. 243637Snate * (Yes this is cheesy, but it makes the X386 server happy, so...) 244637Snate */ 24512675Sjulianstatic int 246144783Simpmseread(struct cdev *dev, struct uio *uio, int ioflag) 247637Snate{ 248191320Sed mse_softc_t *sc = dev->si_drv1; 249272956Sjhb int xfer, error; 250637Snate 251637Snate /* 252637Snate * If there are no protocol bytes to be read, set up a new protocol 253637Snate * packet. 254637Snate */ 255272956Sjhb MSE_LOCK(sc); 256272956Sjhb while (sc->sc_flags & MSESC_READING) { 257272956Sjhb if (MSE_NBLOCKIO(dev)) { 258272956Sjhb MSE_UNLOCK(sc); 259272956Sjhb return (0); 260272956Sjhb } 261272956Sjhb sc->sc_flags |= MSESC_WANT; 262272956Sjhb error = mtx_sleep(sc, &sc->sc_lock, MSEPRI | PCATCH, "mseread", 263272956Sjhb 0); 264272956Sjhb if (error) { 265272956Sjhb MSE_UNLOCK(sc); 266272956Sjhb return (error); 267272956Sjhb } 268272956Sjhb } 269272956Sjhb sc->sc_flags |= MSESC_READING; 270272956Sjhb xfer = 0; 27131603Syokota if (sc->sc_bytesread >= sc->mode.packetsize) { 272637Snate while (sc->sc_deltax == 0 && sc->sc_deltay == 0 && 273637Snate (sc->sc_obuttons ^ sc->sc_buttons) == 0) { 274272956Sjhb if (MSE_NBLOCKIO(dev)) 275272956Sjhb goto out; 276637Snate sc->sc_flags |= MSESC_WANT; 277272956Sjhb error = mtx_sleep(sc, &sc->sc_lock, MSEPRI | PCATCH, 27846571Speter "mseread", 0); 279272956Sjhb if (error) 280272956Sjhb goto out; 281637Snate } 282637Snate 283637Snate /* 284637Snate * Generate protocol bytes. 285637Snate * For some reason X386 expects 5 bytes but never uses 286637Snate * the fourth or fifth? 287637Snate */ 28831603Syokota sc->sc_bytes[0] = sc->mode.syncmask[1] 28931603Syokota | (sc->sc_buttons & ~sc->mode.syncmask[0]); 290637Snate if (sc->sc_deltax > 127) 291637Snate sc->sc_deltax = 127; 292637Snate if (sc->sc_deltax < -127) 293637Snate sc->sc_deltax = -127; 294637Snate sc->sc_deltay = -sc->sc_deltay; /* Otherwise mousey goes wrong way */ 295637Snate if (sc->sc_deltay > 127) 296637Snate sc->sc_deltay = 127; 297637Snate if (sc->sc_deltay < -127) 298637Snate sc->sc_deltay = -127; 299637Snate sc->sc_bytes[1] = sc->sc_deltax; 300637Snate sc->sc_bytes[2] = sc->sc_deltay; 301637Snate sc->sc_bytes[3] = sc->sc_bytes[4] = 0; 30231603Syokota sc->sc_bytes[5] = sc->sc_bytes[6] = 0; 30331603Syokota sc->sc_bytes[7] = MOUSE_SYS_EXTBUTTONS; 304637Snate sc->sc_obuttons = sc->sc_buttons; 305637Snate sc->sc_deltax = sc->sc_deltay = 0; 306637Snate sc->sc_bytesread = 0; 307637Snate } 30831603Syokota xfer = min(uio->uio_resid, sc->mode.packetsize - sc->sc_bytesread); 309272956Sjhb MSE_UNLOCK(sc); 31046571Speter error = uiomove(&sc->sc_bytes[sc->sc_bytesread], xfer, uio); 311272956Sjhb MSE_LOCK(sc); 312272956Sjhbout: 313272956Sjhb sc->sc_flags &= ~MSESC_READING; 314272956Sjhb if (error == 0) 315272956Sjhb sc->sc_bytesread += xfer; 316272956Sjhb if (sc->sc_flags & MSESC_WANT) { 317272956Sjhb sc->sc_flags &= ~MSESC_WANT; 318272956Sjhb MSE_UNLOCK(sc); 319272956Sjhb wakeup(sc); 320272956Sjhb } else 321272956Sjhb MSE_UNLOCK(sc); 322272956Sjhb return (error); 323637Snate} 324637Snate 325637Snate/* 32631603Syokota * mseioctl: process ioctl commands. 32731603Syokota */ 32831603Syokotastatic int 329144783Simpmseioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) 33031603Syokota{ 331191320Sed mse_softc_t *sc = dev->si_drv1; 33231603Syokota mousestatus_t status; 33331603Syokota int err = 0; 33431603Syokota 33531603Syokota switch (cmd) { 33631603Syokota 33731603Syokota case MOUSE_GETHWINFO: 338272956Sjhb MSE_LOCK(sc); 33931603Syokota *(mousehw_t *)addr = sc->hw; 34031603Syokota if (sc->mode.level == 0) 34131603Syokota ((mousehw_t *)addr)->model = MOUSE_MODEL_GENERIC; 342272956Sjhb MSE_UNLOCK(sc); 34331603Syokota break; 34431603Syokota 34531603Syokota case MOUSE_GETMODE: 346272956Sjhb MSE_LOCK(sc); 34731603Syokota *(mousemode_t *)addr = sc->mode; 34831603Syokota switch (sc->mode.level) { 34931603Syokota case 0: 35031603Syokota break; 35131603Syokota case 1: 35231603Syokota ((mousemode_t *)addr)->protocol = MOUSE_PROTO_SYSMOUSE; 35331603Syokota ((mousemode_t *)addr)->syncmask[0] = MOUSE_SYS_SYNCMASK; 35431603Syokota ((mousemode_t *)addr)->syncmask[1] = MOUSE_SYS_SYNC; 35531603Syokota break; 35631603Syokota } 357272956Sjhb MSE_UNLOCK(sc); 35831603Syokota break; 35931603Syokota 36031603Syokota case MOUSE_SETMODE: 36131603Syokota switch (((mousemode_t *)addr)->level) { 36231603Syokota case 0: 36331603Syokota case 1: 36431603Syokota break; 36531603Syokota default: 36631603Syokota return (EINVAL); 36731603Syokota } 368272956Sjhb MSE_LOCK(sc); 369272956Sjhb if (((mousemode_t *)addr)->accelfactor < -1) { 370272956Sjhb MSE_UNLOCK(sc); 37131603Syokota return (EINVAL); 372272956Sjhb } else if (((mousemode_t *)addr)->accelfactor >= 0) 37331603Syokota sc->mode.accelfactor = 37431603Syokota ((mousemode_t *)addr)->accelfactor; 37531603Syokota sc->mode.level = ((mousemode_t *)addr)->level; 37631603Syokota switch (sc->mode.level) { 37731603Syokota case 0: 37831603Syokota sc->sc_bytesread = sc->mode.packetsize 37931603Syokota = MOUSE_MSC_PACKETSIZE; 38031603Syokota break; 38131603Syokota case 1: 38231603Syokota sc->sc_bytesread = sc->mode.packetsize 38331603Syokota = MOUSE_SYS_PACKETSIZE; 38431603Syokota break; 38531603Syokota } 386272956Sjhb MSE_UNLOCK(sc); 38731603Syokota break; 38831603Syokota 38931603Syokota case MOUSE_GETLEVEL: 390272956Sjhb MSE_LOCK(sc); 39131603Syokota *(int *)addr = sc->mode.level; 392272956Sjhb MSE_UNLOCK(sc); 39331603Syokota break; 39431603Syokota 39531603Syokota case MOUSE_SETLEVEL: 39631603Syokota switch (*(int *)addr) { 39731603Syokota case 0: 398272956Sjhb MSE_LOCK(sc); 39931603Syokota sc->mode.level = *(int *)addr; 40031603Syokota sc->sc_bytesread = sc->mode.packetsize 40131603Syokota = MOUSE_MSC_PACKETSIZE; 402272956Sjhb MSE_UNLOCK(sc); 40331603Syokota break; 40431603Syokota case 1: 405272956Sjhb MSE_LOCK(sc); 40631603Syokota sc->mode.level = *(int *)addr; 40731603Syokota sc->sc_bytesread = sc->mode.packetsize 40831603Syokota = MOUSE_SYS_PACKETSIZE; 409272956Sjhb MSE_UNLOCK(sc); 41031603Syokota break; 41131603Syokota default: 41231603Syokota return (EINVAL); 41331603Syokota } 41431603Syokota break; 41531603Syokota 41631603Syokota case MOUSE_GETSTATUS: 417272956Sjhb MSE_LOCK(sc); 41831603Syokota status = sc->status; 41931603Syokota sc->status.flags = 0; 42031603Syokota sc->status.obutton = sc->status.button; 42131603Syokota sc->status.button = 0; 42231603Syokota sc->status.dx = 0; 42331603Syokota sc->status.dy = 0; 42431603Syokota sc->status.dz = 0; 425272956Sjhb MSE_UNLOCK(sc); 42631603Syokota *(mousestatus_t *)addr = status; 42731603Syokota break; 42831603Syokota 42931603Syokota case MOUSE_READSTATE: 43031603Syokota case MOUSE_READDATA: 43131603Syokota return (ENODEV); 43231603Syokota 43331603Syokota#if (defined(MOUSE_GETVARS)) 43431603Syokota case MOUSE_GETVARS: 43531603Syokota case MOUSE_SETVARS: 43631603Syokota return (ENODEV); 43731603Syokota#endif 43831603Syokota 43931603Syokota default: 44031603Syokota return (ENOTTY); 44131603Syokota } 44231603Syokota return (err); 44331603Syokota} 44431603Syokota 44531603Syokota/* 44629368Speter * msepoll: check for mouse input to be processed. 447637Snate */ 44812675Sjulianstatic int 449144783Simpmsepoll(struct cdev *dev, int events, struct thread *td) 450637Snate{ 451191320Sed mse_softc_t *sc = dev->si_drv1; 45229368Speter int revents = 0; 453637Snate 454272956Sjhb MSE_LOCK(sc); 45546568Speter if (events & (POLLIN | POLLRDNORM)) { 45631603Syokota if (sc->sc_bytesread != sc->mode.packetsize || 45731603Syokota sc->sc_deltax != 0 || sc->sc_deltay != 0 || 45829368Speter (sc->sc_obuttons ^ sc->sc_buttons) != 0) 45929368Speter revents |= events & (POLLIN | POLLRDNORM); 460272956Sjhb else 46183366Sjulian selrecord(td, &sc->sc_selp); 46246568Speter } 463272956Sjhb MSE_UNLOCK(sc); 46429368Speter return (revents); 465637Snate} 466637Snate 467637Snate/* 46858229Syokota * msetimeout: watchdog timer routine. 46958229Syokota */ 47058229Syokotastatic void 471144783Simpmsetimeout(void *arg) 47258229Syokota{ 473130585Sphk struct cdev *dev; 47458229Syokota mse_softc_t *sc; 47558229Syokota 476130585Sphk dev = (struct cdev *)arg; 477191320Sed sc = dev->si_drv1; 478272956Sjhb MSE_ASSERT_LOCKED(sc); 47958229Syokota if (sc->sc_watchdog) { 48058229Syokota if (bootverbose) 481191320Sed printf("%s: lost interrupt?\n", devtoname(dev)); 482272956Sjhb mseintr_locked(sc); 48358229Syokota } 48458229Syokota sc->sc_watchdog = TRUE; 485272956Sjhb callout_schedule(&sc->sc_callout, hz); 48658229Syokota} 48758229Syokota 48858229Syokota/* 489637Snate * mseintr: update mouse status. sc_deltax and sc_deltay are accumulative. 490637Snate */ 49140565Sbdestatic void 492144783Simpmseintr(void *arg) 493637Snate{ 494272956Sjhb mse_softc_t *sc = arg; 495272956Sjhb 496272956Sjhb MSE_LOCK(sc); 497272956Sjhb mseintr_locked(sc); 498272956Sjhb MSE_UNLOCK(sc); 499272956Sjhb} 500272956Sjhb 501272956Sjhbstatic void 502272956Sjhbmseintr_locked(mse_softc_t *sc) 503272956Sjhb{ 50431603Syokota /* 50531603Syokota * the table to turn MouseSystem button bits (MOUSE_MSC_BUTTON?UP) 50631603Syokota * into `mousestatus' button bits (MOUSE_BUTTON?DOWN). 50731603Syokota */ 50831603Syokota static int butmap[8] = { 50931603Syokota 0, 51031603Syokota MOUSE_BUTTON3DOWN, 51131603Syokota MOUSE_BUTTON2DOWN, 51231603Syokota MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN, 51331603Syokota MOUSE_BUTTON1DOWN, 51431603Syokota MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN, 51531603Syokota MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN, 51631603Syokota MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN 51731603Syokota }; 51831603Syokota int dx, dy, but; 51931603Syokota int sign; 520637Snate 521637Snate#ifdef DEBUG 522637Snate static int mse_intrcnt = 0; 523637Snate if((mse_intrcnt++ % 10000) == 0) 524637Snate printf("mseintr\n"); 525637Snate#endif /* DEBUG */ 526637Snate if ((sc->sc_flags & MSESC_OPEN) == 0) 527637Snate return; 528637Snate 529272956Sjhb (*sc->sc_getmouse)(sc->sc_port, &dx, &dy, &but); 53031603Syokota if (sc->mode.accelfactor > 0) { 53131603Syokota sign = (dx < 0); 53231603Syokota dx = dx * dx / sc->mode.accelfactor; 53331603Syokota if (dx == 0) 53431603Syokota dx = 1; 53531603Syokota if (sign) 53631603Syokota dx = -dx; 53731603Syokota sign = (dy < 0); 53831603Syokota dy = dy * dy / sc->mode.accelfactor; 53931603Syokota if (dy == 0) 54031603Syokota dy = 1; 54131603Syokota if (sign) 54231603Syokota dy = -dy; 54331603Syokota } 54431603Syokota sc->sc_deltax += dx; 54531603Syokota sc->sc_deltay += dy; 54631603Syokota sc->sc_buttons = but; 547637Snate 54831603Syokota but = butmap[~but & MOUSE_MSC_BUTTONS]; 54931603Syokota sc->status.dx += dx; 55031603Syokota sc->status.dy += dy; 55131603Syokota sc->status.flags |= ((dx || dy) ? MOUSE_POSCHANGED : 0) 55231603Syokota | (sc->status.button ^ but); 55331603Syokota sc->status.button = but; 55431603Syokota 55558229Syokota sc->sc_watchdog = FALSE; 55658229Syokota 557637Snate /* 558637Snate * If mouse state has changed, wake up anyone wanting to know. 559637Snate */ 560637Snate if (sc->sc_deltax != 0 || sc->sc_deltay != 0 || 561637Snate (sc->sc_obuttons ^ sc->sc_buttons) != 0) { 5628876Srgrimes if (sc->sc_flags & MSESC_WANT) { 5638876Srgrimes sc->sc_flags &= ~MSESC_WANT; 564111748Sdes wakeup(sc); 5658876Srgrimes } 566122352Stanimura selwakeuppri(&sc->sc_selp, MSEPRI); 567637Snate } 568637Snate} 569