Separated out the function to place records in the mouse buffer.

Add acknowledgement records to the buffer following origin or bounding
box changes.
Removed prototype for strncmp().
Added support for switch mouse reports between absolute and relative
positions.
This commit is contained in:
mark 1996-10-15 21:06:51 +00:00
parent 65b094f18f
commit e7e591d3b5
4 changed files with 454 additions and 88 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pms.c,v 1.5 1996/10/13 03:06:27 christos Exp $ */ /* $NetBSD: pms.c,v 1.6 1996/10/15 21:06:51 mark Exp $ */
/*- /*-
* Copyright (c) 1996 D.C. Tsen * Copyright (c) 1996 D.C. Tsen
@ -57,6 +57,7 @@
#include <sys/signalvar.h> #include <sys/signalvar.h>
#include <sys/vnode.h> #include <sys/vnode.h>
#include <sys/device.h> #include <sys/device.h>
#include <sys/poll.h>
#include <machine/cpu.h> #include <machine/cpu.h>
#include <machine/katelib.h> #include <machine/katelib.h>
@ -83,7 +84,7 @@ struct pms_softc { /* driver status information */
struct device sc_dev; struct device sc_dev;
irqhandler_t sc_ih; irqhandler_t sc_ih;
struct proc *proc; struct proc *sc_proc;
struct clist sc_q; struct clist sc_q;
struct selinfo sc_rsel; struct selinfo sc_rsel;
u_int sc_state; /* mouse driver state */ u_int sc_state; /* mouse driver state */
@ -96,11 +97,12 @@ struct pms_softc { /* driver status information */
int lastx, lasty, lastb; int lastx, lasty, lastb;
}; };
int pmsprobe __P((struct device *, void *, void *)); int pmsprobe __P((struct device *, void *, void *));
void pmsattach __P((struct device *, struct device *, void *)); void pmsattach __P((struct device *, struct device *, void *));
int pmsintr __P((void *)); int pmsintr __P((void *));
int pmsinit __P(()); int pmsinit __P(());
void pmswatchdog __P((void *)); void pmswatchdog __P((void *));
void pmsputbuffer __P((struct pms_softc *sc, struct mousebufrec *buf));
struct cfattach pms_ca = { struct cfattach pms_ca = {
sizeof(struct pms_softc), pmsprobe, pmsattach sizeof(struct pms_softc), pmsprobe, pmsattach
@ -200,7 +202,7 @@ pmsinit()
case RPC600_IOMD_ID: case RPC600_IOMD_ID:
return(0); return(0);
break; break;
case RC7500_IOC_ID: case ARM7500_IOC_ID:
break; break;
default: default:
printf("pms: Unknown IOMD id=%04x", id); printf("pms: Unknown IOMD id=%04x", id);
@ -284,7 +286,7 @@ pmsattach(parent, self, aux)
if (mb->mb_irq != IRQUNK) if (mb->mb_irq != IRQUNK)
sc->sc_ih.ih_num = mb->mb_irq; sc->sc_ih.ih_num = mb->mb_irq;
else else
#ifdef RC7500 #ifdef CPU_ARM7500
sc->sc_ih.ih_num = IRQ_MSDRX; sc->sc_ih.ih_num = IRQ_MSDRX;
#else #else
panic("pms: No IRQ specified for pms interrupt handler\n"); panic("pms: No IRQ specified for pms interrupt handler\n");
@ -313,7 +315,7 @@ pmsopen(dev, flag, mode, p)
if (clalloc(&sc->sc_q, PMS_BSIZE, 0) == -1) if (clalloc(&sc->sc_q, PMS_BSIZE, 0) == -1)
return ENOMEM; return ENOMEM;
sc->proc = p; sc->sc_proc = p;
sc->sc_state |= PMS_OPEN; sc->sc_state |= PMS_OPEN;
sc->sc_status = 0; sc->sc_status = 0;
sc->sc_x = sc->sc_y = 0; sc->sc_x = sc->sc_y = 0;
@ -343,7 +345,7 @@ pmsclose(dev, flag, mode, p)
if (irq_release(IRQ_INSTRUCT, &sc->sc_ih) != 0) if (irq_release(IRQ_INSTRUCT, &sc->sc_ih) != 0)
panic("Cannot release MOUSE IRQ\n"); panic("Cannot release MOUSE IRQ\n");
sc->proc = NULL; sc->sc_proc = NULL;
sc->sc_state &= ~PMS_OPEN; sc->sc_state &= ~PMS_OPEN;
sc->sc_x = sc->sc_y = 0; sc->sc_x = sc->sc_y = 0;
@ -427,15 +429,33 @@ pmsioctl(dev, cmd, addr, flag, p)
case MOUSEIOC_SETBOUNDS: case MOUSEIOC_SETBOUNDS:
{ {
register struct mouse_boundingbox *bo = (void *) addr; register struct mouse_boundingbox *bo = (void *) addr;
struct mousebufrec buffer;
sc->boundx = bo->x; sc->boundy = bo->y; sc->boundx = bo->x; sc->boundy = bo->y;
sc->bounda = bo->a; sc->boundb = bo->b; sc->bounda = bo->a; sc->boundb = bo->b;
buffer.status = IOC_ACK;
buffer.x = sc->origx;
buffer.y = sc->origy;
#ifdef MOUSE_IOC_ACK
pmsputbuffer(sc, &buffer);
#endif
break; break;
} }
case MOUSEIOC_SETORIGIN: case MOUSEIOC_SETORIGIN:
{ {
register struct mouse_origin *oo = (void *) addr; register struct mouse_origin *oo = (void *) addr;
struct mousebufrec buffer;
sc->origx = oo->x; sc->origx = oo->x;
sc->origy = oo->y; sc->origy = oo->y;
buffer.status = IOC_ACK;
buffer.x = sc->origx;
buffer.y = sc->origy;
#ifdef MOUSE_IOC_ACK
pmsputbuffer(sc, &buffer);
#endif
break; break;
} }
case MOUSEIOC_GETBOUNDS: case MOUSEIOC_GETBOUNDS:
@ -524,7 +544,7 @@ pmsintr(arg)
if ((sc->sc_state & PMS_OPEN) == 0) { if ((sc->sc_state & PMS_OPEN) == 0) {
/* Interrupts are not expected. Discard the byte. */ /* Interrupts are not expected. Discard the byte. */
pms_flush(); pms_flush();
return(-1); return(-1); /* Could have been ours but pass it on */
} }
switch (state) { switch (state) {
@ -585,7 +605,7 @@ pmsintr(arg)
/* Add this event to the queue. */ /* Add this event to the queue. */
b = buttons & BUTSTATMASK; b = buttons & BUTSTATMASK;
mbuffer.status = b | (b ^ sc->lastb) << 3 mbuffer.status = b | (b ^ sc->lastb) << 3
| (((sc->sc_x==sc->lastx) && (sc->sc_y==sc->lasty))?0:0x40); | (((sc->sc_x==sc->lastx) && (sc->sc_y==sc->lasty))?0:MOVEMENT);
mbuffer.x = sc->sc_x * 2; mbuffer.x = sc->sc_x * 2;
mbuffer.y = sc->sc_y * 2; mbuffer.y = sc->sc_y * 2;
microtime(&mbuffer.event_time); microtime(&mbuffer.event_time);
@ -602,15 +622,16 @@ pmsintr(arg)
wakeup((caddr_t)sc); wakeup((caddr_t)sc);
} }
if (dosignal) if (dosignal)
psignal(sc->proc, SIGIO); psignal(sc->sc_proc, SIGIO);
} }
break; break;
} }
return(0); return(1); /* Claim interrupt */
} }
#if 0
int int
pmsselect(dev, rw, p) pmsselect(dev, rw, p)
dev_t dev; dev_t dev;
@ -635,6 +656,31 @@ pmsselect(dev, rw, p)
return ret; return ret;
} }
#else
int
pmspoll(dev, events, p)
dev_t dev;
int events;
struct proc *p;
{
struct pms_softc *sc = pms_cd.cd_devs[PMSUNIT(dev)];
int revents = 0;
int s = spltty();
if (events & (POLLIN | POLLRDNORM))
if (sc->sc_q.c_cc > 0)
revents |= events & (POLLIN | POLLRDNORM);
else
selrecord(p, &sc->sc_rsel);
splx(s);
return (revents);
}
#endif
void void
pmswatchdog(arg) pmswatchdog(arg)
void *arg; void *arg;
@ -648,3 +694,31 @@ pmswatchdog(arg)
splx(s); splx(s);
} }
} }
void
pmsputbuffer(sc, buffer)
struct pms_softc *sc;
struct mousebufrec *buffer;
{
int s;
int dosignal=0;
/* Time stamp the buffer */
microtime(&buffer->event_time);
if (sc->sc_q.c_cc==0)
dosignal=1;
s=spltty();
(void) b_to_q((char *)buffer, sizeof(*buffer), &sc->sc_q);
(void)splx(s);
selwakeup(&sc->sc_rsel);
if (sc->sc_state & PMS_ASLP) {
sc->sc_state &= ~PMS_ASLP;
wakeup((caddr_t)sc);
}
if (dosignal)
psignal(sc->sc_proc, SIGIO);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: qms.c,v 1.9 1996/10/13 03:06:28 christos Exp $ */ /* $NetBSD: qms.c,v 1.10 1996/10/15 21:06:53 mark Exp $ */
/* /*
* Copyright (c) Scott Stevens 1995 All rights reserved * Copyright (c) Scott Stevens 1995 All rights reserved
@ -51,6 +51,7 @@
#include <sys/signalvar.h> #include <sys/signalvar.h>
#include <sys/vnode.h> #include <sys/vnode.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/poll.h>
#include <arm32/mainbus/mainbus.h> #include <arm32/mainbus/mainbus.h>
#include <machine/irqhandler.h> #include <machine/irqhandler.h>
@ -73,12 +74,13 @@ struct quadmouse_softc {
#define QMOUSE_OPEN 0x01 #define QMOUSE_OPEN 0x01
#define QMOUSE_ASLEEP 0x02 #define QMOUSE_ASLEEP 0x02
int sc_state; int sc_state;
int mode;
int boundx, boundy, bounda, boundb; /* Bounding box. x,y is bottom left */ int boundx, boundy, bounda, boundb; /* Bounding box. x,y is bottom left */
int origx, origy; int origx, origy;
int xmult, ymult; /* Multipliers */ int xmult, ymult; /* Multipliers */
int lastx, lasty, lastb; int lastx, lasty, lastb;
struct proc *proc; struct proc *sc_proc;
struct clist buffer; struct clist sc_buffer;
}; };
int quadmouseprobe __P((struct device *, void *, void *)); int quadmouseprobe __P((struct device *, void *, void *));
@ -86,9 +88,8 @@ void quadmouseattach __P((struct device *, struct device *, void *));
int quadmouseopen __P((dev_t, int, int, struct proc *)); int quadmouseopen __P((dev_t, int, int, struct proc *));
int quadmouseclose __P((dev_t, int, int, struct proc *)); int quadmouseclose __P((dev_t, int, int, struct proc *));
int strncmp __P((const char *, const char *, size_t)); int quadmouseintr __P((struct quadmouse_softc *sc));
void quadmouseputbuffer __P((struct quadmouse_softc *sc, struct mousebufrec *buf));
int quadmouseintr (struct quadmouse_softc *);
struct cfattach quadmouse_ca = { struct cfattach quadmouse_ca = {
sizeof(struct quadmouse_softc), quadmouseprobe, quadmouseattach sizeof(struct quadmouse_softc), quadmouseprobe, quadmouseattach
@ -195,16 +196,18 @@ quadmouseopen(dev, flag, mode, p)
if (sc->sc_state & QMOUSE_OPEN) return(EBUSY); if (sc->sc_state & QMOUSE_OPEN) return(EBUSY);
sc->proc = p; sc->sc_proc = p;
sc->lastx = -1; sc->lastx = -1;
sc->lasty = -1; sc->lasty = -1;
sc->lastb = -1; sc->lastb = -1;
/* initialise buffer */ /* initialise buffer */
if (clalloc(&sc->buffer, QMOUSE_BSIZE, 0) == -1) if (clalloc(&sc->sc_buffer, QMOUSE_BSIZE, 0) == -1)
return(ENOMEM); return(ENOMEM);
sc->mode = MOUSEMODE_ABS;
sc->sc_state |= QMOUSE_OPEN; sc->sc_state |= QMOUSE_OPEN;
if (sc->sc_irqnum == IRQ_TIMER1) { if (sc->sc_irqnum == IRQ_TIMER1) {
@ -233,10 +236,10 @@ quadmouseclose(dev, flag, mode, p)
if (irq_release(sc->sc_irqnum, &sc->sc_ih) != 0) if (irq_release(sc->sc_irqnum, &sc->sc_ih) != 0)
panic("Cannot release IRQ %d\n", sc->sc_irqnum); panic("Cannot release IRQ %d\n", sc->sc_irqnum);
sc->proc = NULL; sc->sc_proc = NULL;
sc->sc_state = 0; sc->sc_state = 0;
clfree(&sc->buffer); clfree(&sc->sc_buffer);
return(0); return(0);
} }
@ -256,7 +259,7 @@ quadmouseread(dev, uio, flag)
error = 0; error = 0;
s=spltty(); s=spltty();
while(sc->buffer.c_cc==0) { while(sc->sc_buffer.c_cc==0) {
if(flag & IO_NDELAY) { if(flag & IO_NDELAY) {
(void)splx(s); (void)splx(s);
return(EWOULDBLOCK); return(EWOULDBLOCK);
@ -269,12 +272,12 @@ quadmouseread(dev, uio, flag)
} }
} }
while(sc->buffer.c_cc>0 && uio->uio_resid>0) { while(sc->sc_buffer.c_cc>0 && uio->uio_resid>0) {
length=min(sc->buffer.c_cc, uio->uio_resid); length=min(sc->sc_buffer.c_cc, uio->uio_resid);
if(length>sizeof(buffer)) if(length>sizeof(buffer))
length=sizeof(buffer); length=sizeof(buffer);
(void) q_to_b(&sc->buffer, buffer, length); (void) q_to_b(&sc->sc_buffer, buffer, length);
if ((error = (uiomove(buffer, length, uio)))) if ((error = (uiomove(buffer, length, uio))))
break; break;
@ -327,29 +330,77 @@ quadmouseioctl(dev, cmd, data, flag, p)
register struct mouse_state *co = (void *)data; register struct mouse_state *co = (void *)data;
WriteWord(IOMD_MOUSEX, co->x); WriteWord(IOMD_MOUSEX, co->x);
WriteWord(IOMD_MOUSEY, co->y); WriteWord(IOMD_MOUSEY, co->y);
/* Silly, but here for completeness, just incase */
/* the hardware supports it *giggle* */
/* This is not writable -- mark -- technically this should fault */
/* WriteWord ( IO_MOUSE_BUTTONS, co->buttons );*/
return 0; return 0;
} }
case MOUSEIOC_SETBOUNDS: case MOUSEIOC_SETBOUNDS:
{ {
register struct mouse_boundingbox *bo = (void *)data; register struct mouse_boundingbox *bo = (void *)data;
sc->boundx = bo->x; sc->boundy = bo->y; struct mousebufrec buffer;
sc->bounda = bo->a; sc->boundb = bo->b; int s;
#ifdef MOUSE_IOC_ACK
s = spltty();
#endif
sc->boundx = bo->x;
sc->boundy = bo->y;
sc->bounda = bo->a;
sc->boundb = bo->b;
buffer.status = IOC_ACK;
buffer.x = sc->origx;
buffer.y = sc->origy;
#ifdef MOUSE_IOC_ACK
if (sc->sc_buffer.c_cc > 0)
printf("qms: setting bounding with non empty buffer (%d)\n", sc->sc_buffer.c_cc);
quadmouseputbuffer(sc, &buffer);
(void)splx(s);
#endif
return 0;
}
case MOUSEIOC_SETMODE:
{
struct mousebufrec buffer;
int s;
#ifdef MOUSE_IOC_ACK
s = spltty();
#endif
sc->mode = *(u_int *)data;
buffer.status = IOC_ACK;
buffer.x = sc->origx;
buffer.y = sc->origy;
#ifdef MOUSE_IOC_ACK
if (sc->sc_buffer.c_cc > 0)
printf("qms: setting mode with non empty buffer (%d)\n", sc->sc_buffer.c_cc);
quadmouseputbuffer(sc, &buffer);
(void)splx(s);
#endif
return 0; return 0;
} }
case MOUSEIOC_SETORIGIN: case MOUSEIOC_SETORIGIN:
{ {
register struct mouse_origin *oo = (void *)data; register struct mouse_origin *oo = (void *)data;
/* int oldx, oldy;*/ struct mousebufrec buffer;
int s;
#ifdef MOUSE_IOC_ACK
s = spltty();
#endif
/* Need to fix up! */ /* Need to fix up! */
sc->origx = oo->x; sc->origx = oo->x;
sc->origy = oo->y; sc->origy = oo->y;
buffer.status = IOC_ACK;
buffer.x = sc->origx;
buffer.y = sc->origy;
#ifdef MOUSE_IOC_ACK
if (sc->sc_buffer.c_cc > 0)
printf("qms: setting origin with non empty buffer (%d)\n", sc->sc_buffer.c_cc);
quadmouseputbuffer(sc, &buffer);
(void)splx(s);
#endif
return 0; return 0;
} }
case MOUSEIOC_GETSTATE: case MOUSEIOC_GETSTATE:
@ -396,16 +447,21 @@ quadmouseintr(sc)
b >>= 4; b >>= 4;
if (x != sc->lastx || y != sc->lasty || b != sc->lastb) { if (x != sc->lastx || y != sc->lasty || b != sc->lastb) {
/* Mouse state changed */ /* Mouse state changed */
buffer.status = b | ( b ^ sc->lastb) << 3 | (((x==sc->lastx) && (y==sc->lasty))?0:0x40); buffer.status = b | ( b ^ sc->lastb) << 3 | (((x==sc->lastx) && (y==sc->lasty))?0:MOVEMENT);
if((sc->mode & MOUSEMODE_REL) == MOUSEMODE_REL) {
sc->origx = sc->origy = 0;
WriteWord(IOMD_MOUSEX, sc->origx);
WriteWord(IOMD_MOUSEY, sc->origy);
}
buffer.x = x; buffer.x = x;
buffer.y = y; buffer.y = y;
microtime(&buffer.event_time); microtime(&buffer.event_time);
if(sc->buffer.c_cc==0) if(sc->sc_buffer.c_cc==0)
dosignal=1; dosignal=1;
s=spltty(); s=spltty();
(void) b_to_q((char *)&buffer, sizeof(buffer), &sc->buffer); (void) b_to_q((char *)&buffer, sizeof(buffer), &sc->sc_buffer);
(void)splx(s); (void)splx(s);
selwakeup(&sc->sc_rsel); selwakeup(&sc->sc_rsel);
@ -415,7 +471,7 @@ quadmouseintr(sc)
} }
if(dosignal) if(dosignal)
psignal(sc->proc, SIGIO); psignal(sc->sc_proc, SIGIO);
sc->lastx = x; sc->lastx = x;
sc->lasty = y; sc->lasty = y;
@ -426,6 +482,7 @@ quadmouseintr(sc)
return(0); /* Pass interrupt on down the chain */ return(0); /* Pass interrupt on down the chain */
} }
#if 0
int int
quadmouseselect(dev, rw, p) quadmouseselect(dev, rw, p)
dev_t dev; dev_t dev;
@ -440,7 +497,7 @@ quadmouseselect(dev, rw, p)
return 0; return 0;
s=spltty(); s=spltty();
if(sc->buffer.c_cc > 0) { if(sc->sc_buffer.c_cc > 0) {
selrecord(p, &sc->sc_rsel); selrecord(p, &sc->sc_rsel);
(void)splx(s); (void)splx(s);
return 0; return 0;
@ -449,4 +506,56 @@ quadmouseselect(dev, rw, p)
return 1; return 1;
} }
#else
int
quadmousepoll(dev, events, p)
dev_t dev;
int events;
struct proc *p;
{
struct quadmouse_softc *sc = quadmouse_cd.cd_devs[minor(dev)];
int revents = 0;
int s = spltty();
if (events & (POLLIN | POLLRDNORM))
if (sc->sc_buffer.c_cc > 0)
revents |= events & (POLLIN | POLLRDNORM);
else
selrecord(p, &sc->sc_rsel);
splx(s);
return (revents);
}
#endif
void
quadmouseputbuffer(sc, buffer)
struct quadmouse_softc *sc;
struct mousebufrec *buffer;
{
int s;
int dosignal=0;
/* Time stamp the buffer */
microtime(&buffer->event_time);
if(sc->sc_buffer.c_cc==0)
dosignal=1;
s=spltty();
(void) b_to_q((char *)buffer, sizeof(*buffer), &sc->sc_buffer);
(void)splx(s);
selwakeup(&sc->sc_rsel);
if(sc->sc_state & QMOUSE_ASLEEP) {
sc->sc_state &= ~QMOUSE_ASLEEP;
wakeup((caddr_t)sc);
}
if(dosignal)
psignal(sc->sc_proc, SIGIO);
}
/* End of quadmouse.c */ /* End of quadmouse.c */

View File

@ -1,4 +1,4 @@
/* $NetBSD: pms.c,v 1.5 1996/10/13 03:06:27 christos Exp $ */ /* $NetBSD: pms.c,v 1.6 1996/10/15 21:06:51 mark Exp $ */
/*- /*-
* Copyright (c) 1996 D.C. Tsen * Copyright (c) 1996 D.C. Tsen
@ -57,6 +57,7 @@
#include <sys/signalvar.h> #include <sys/signalvar.h>
#include <sys/vnode.h> #include <sys/vnode.h>
#include <sys/device.h> #include <sys/device.h>
#include <sys/poll.h>
#include <machine/cpu.h> #include <machine/cpu.h>
#include <machine/katelib.h> #include <machine/katelib.h>
@ -83,7 +84,7 @@ struct pms_softc { /* driver status information */
struct device sc_dev; struct device sc_dev;
irqhandler_t sc_ih; irqhandler_t sc_ih;
struct proc *proc; struct proc *sc_proc;
struct clist sc_q; struct clist sc_q;
struct selinfo sc_rsel; struct selinfo sc_rsel;
u_int sc_state; /* mouse driver state */ u_int sc_state; /* mouse driver state */
@ -96,11 +97,12 @@ struct pms_softc { /* driver status information */
int lastx, lasty, lastb; int lastx, lasty, lastb;
}; };
int pmsprobe __P((struct device *, void *, void *)); int pmsprobe __P((struct device *, void *, void *));
void pmsattach __P((struct device *, struct device *, void *)); void pmsattach __P((struct device *, struct device *, void *));
int pmsintr __P((void *)); int pmsintr __P((void *));
int pmsinit __P(()); int pmsinit __P(());
void pmswatchdog __P((void *)); void pmswatchdog __P((void *));
void pmsputbuffer __P((struct pms_softc *sc, struct mousebufrec *buf));
struct cfattach pms_ca = { struct cfattach pms_ca = {
sizeof(struct pms_softc), pmsprobe, pmsattach sizeof(struct pms_softc), pmsprobe, pmsattach
@ -200,7 +202,7 @@ pmsinit()
case RPC600_IOMD_ID: case RPC600_IOMD_ID:
return(0); return(0);
break; break;
case RC7500_IOC_ID: case ARM7500_IOC_ID:
break; break;
default: default:
printf("pms: Unknown IOMD id=%04x", id); printf("pms: Unknown IOMD id=%04x", id);
@ -284,7 +286,7 @@ pmsattach(parent, self, aux)
if (mb->mb_irq != IRQUNK) if (mb->mb_irq != IRQUNK)
sc->sc_ih.ih_num = mb->mb_irq; sc->sc_ih.ih_num = mb->mb_irq;
else else
#ifdef RC7500 #ifdef CPU_ARM7500
sc->sc_ih.ih_num = IRQ_MSDRX; sc->sc_ih.ih_num = IRQ_MSDRX;
#else #else
panic("pms: No IRQ specified for pms interrupt handler\n"); panic("pms: No IRQ specified for pms interrupt handler\n");
@ -313,7 +315,7 @@ pmsopen(dev, flag, mode, p)
if (clalloc(&sc->sc_q, PMS_BSIZE, 0) == -1) if (clalloc(&sc->sc_q, PMS_BSIZE, 0) == -1)
return ENOMEM; return ENOMEM;
sc->proc = p; sc->sc_proc = p;
sc->sc_state |= PMS_OPEN; sc->sc_state |= PMS_OPEN;
sc->sc_status = 0; sc->sc_status = 0;
sc->sc_x = sc->sc_y = 0; sc->sc_x = sc->sc_y = 0;
@ -343,7 +345,7 @@ pmsclose(dev, flag, mode, p)
if (irq_release(IRQ_INSTRUCT, &sc->sc_ih) != 0) if (irq_release(IRQ_INSTRUCT, &sc->sc_ih) != 0)
panic("Cannot release MOUSE IRQ\n"); panic("Cannot release MOUSE IRQ\n");
sc->proc = NULL; sc->sc_proc = NULL;
sc->sc_state &= ~PMS_OPEN; sc->sc_state &= ~PMS_OPEN;
sc->sc_x = sc->sc_y = 0; sc->sc_x = sc->sc_y = 0;
@ -427,15 +429,33 @@ pmsioctl(dev, cmd, addr, flag, p)
case MOUSEIOC_SETBOUNDS: case MOUSEIOC_SETBOUNDS:
{ {
register struct mouse_boundingbox *bo = (void *) addr; register struct mouse_boundingbox *bo = (void *) addr;
struct mousebufrec buffer;
sc->boundx = bo->x; sc->boundy = bo->y; sc->boundx = bo->x; sc->boundy = bo->y;
sc->bounda = bo->a; sc->boundb = bo->b; sc->bounda = bo->a; sc->boundb = bo->b;
buffer.status = IOC_ACK;
buffer.x = sc->origx;
buffer.y = sc->origy;
#ifdef MOUSE_IOC_ACK
pmsputbuffer(sc, &buffer);
#endif
break; break;
} }
case MOUSEIOC_SETORIGIN: case MOUSEIOC_SETORIGIN:
{ {
register struct mouse_origin *oo = (void *) addr; register struct mouse_origin *oo = (void *) addr;
struct mousebufrec buffer;
sc->origx = oo->x; sc->origx = oo->x;
sc->origy = oo->y; sc->origy = oo->y;
buffer.status = IOC_ACK;
buffer.x = sc->origx;
buffer.y = sc->origy;
#ifdef MOUSE_IOC_ACK
pmsputbuffer(sc, &buffer);
#endif
break; break;
} }
case MOUSEIOC_GETBOUNDS: case MOUSEIOC_GETBOUNDS:
@ -524,7 +544,7 @@ pmsintr(arg)
if ((sc->sc_state & PMS_OPEN) == 0) { if ((sc->sc_state & PMS_OPEN) == 0) {
/* Interrupts are not expected. Discard the byte. */ /* Interrupts are not expected. Discard the byte. */
pms_flush(); pms_flush();
return(-1); return(-1); /* Could have been ours but pass it on */
} }
switch (state) { switch (state) {
@ -585,7 +605,7 @@ pmsintr(arg)
/* Add this event to the queue. */ /* Add this event to the queue. */
b = buttons & BUTSTATMASK; b = buttons & BUTSTATMASK;
mbuffer.status = b | (b ^ sc->lastb) << 3 mbuffer.status = b | (b ^ sc->lastb) << 3
| (((sc->sc_x==sc->lastx) && (sc->sc_y==sc->lasty))?0:0x40); | (((sc->sc_x==sc->lastx) && (sc->sc_y==sc->lasty))?0:MOVEMENT);
mbuffer.x = sc->sc_x * 2; mbuffer.x = sc->sc_x * 2;
mbuffer.y = sc->sc_y * 2; mbuffer.y = sc->sc_y * 2;
microtime(&mbuffer.event_time); microtime(&mbuffer.event_time);
@ -602,15 +622,16 @@ pmsintr(arg)
wakeup((caddr_t)sc); wakeup((caddr_t)sc);
} }
if (dosignal) if (dosignal)
psignal(sc->proc, SIGIO); psignal(sc->sc_proc, SIGIO);
} }
break; break;
} }
return(0); return(1); /* Claim interrupt */
} }
#if 0
int int
pmsselect(dev, rw, p) pmsselect(dev, rw, p)
dev_t dev; dev_t dev;
@ -635,6 +656,31 @@ pmsselect(dev, rw, p)
return ret; return ret;
} }
#else
int
pmspoll(dev, events, p)
dev_t dev;
int events;
struct proc *p;
{
struct pms_softc *sc = pms_cd.cd_devs[PMSUNIT(dev)];
int revents = 0;
int s = spltty();
if (events & (POLLIN | POLLRDNORM))
if (sc->sc_q.c_cc > 0)
revents |= events & (POLLIN | POLLRDNORM);
else
selrecord(p, &sc->sc_rsel);
splx(s);
return (revents);
}
#endif
void void
pmswatchdog(arg) pmswatchdog(arg)
void *arg; void *arg;
@ -648,3 +694,31 @@ pmswatchdog(arg)
splx(s); splx(s);
} }
} }
void
pmsputbuffer(sc, buffer)
struct pms_softc *sc;
struct mousebufrec *buffer;
{
int s;
int dosignal=0;
/* Time stamp the buffer */
microtime(&buffer->event_time);
if (sc->sc_q.c_cc==0)
dosignal=1;
s=spltty();
(void) b_to_q((char *)buffer, sizeof(*buffer), &sc->sc_q);
(void)splx(s);
selwakeup(&sc->sc_rsel);
if (sc->sc_state & PMS_ASLP) {
sc->sc_state &= ~PMS_ASLP;
wakeup((caddr_t)sc);
}
if (dosignal)
psignal(sc->sc_proc, SIGIO);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: qmouse.c,v 1.9 1996/10/13 03:06:28 christos Exp $ */ /* $NetBSD: qmouse.c,v 1.10 1996/10/15 21:06:53 mark Exp $ */
/* /*
* Copyright (c) Scott Stevens 1995 All rights reserved * Copyright (c) Scott Stevens 1995 All rights reserved
@ -51,6 +51,7 @@
#include <sys/signalvar.h> #include <sys/signalvar.h>
#include <sys/vnode.h> #include <sys/vnode.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/poll.h>
#include <arm32/mainbus/mainbus.h> #include <arm32/mainbus/mainbus.h>
#include <machine/irqhandler.h> #include <machine/irqhandler.h>
@ -73,12 +74,13 @@ struct quadmouse_softc {
#define QMOUSE_OPEN 0x01 #define QMOUSE_OPEN 0x01
#define QMOUSE_ASLEEP 0x02 #define QMOUSE_ASLEEP 0x02
int sc_state; int sc_state;
int mode;
int boundx, boundy, bounda, boundb; /* Bounding box. x,y is bottom left */ int boundx, boundy, bounda, boundb; /* Bounding box. x,y is bottom left */
int origx, origy; int origx, origy;
int xmult, ymult; /* Multipliers */ int xmult, ymult; /* Multipliers */
int lastx, lasty, lastb; int lastx, lasty, lastb;
struct proc *proc; struct proc *sc_proc;
struct clist buffer; struct clist sc_buffer;
}; };
int quadmouseprobe __P((struct device *, void *, void *)); int quadmouseprobe __P((struct device *, void *, void *));
@ -86,9 +88,8 @@ void quadmouseattach __P((struct device *, struct device *, void *));
int quadmouseopen __P((dev_t, int, int, struct proc *)); int quadmouseopen __P((dev_t, int, int, struct proc *));
int quadmouseclose __P((dev_t, int, int, struct proc *)); int quadmouseclose __P((dev_t, int, int, struct proc *));
int strncmp __P((const char *, const char *, size_t)); int quadmouseintr __P((struct quadmouse_softc *sc));
void quadmouseputbuffer __P((struct quadmouse_softc *sc, struct mousebufrec *buf));
int quadmouseintr (struct quadmouse_softc *);
struct cfattach quadmouse_ca = { struct cfattach quadmouse_ca = {
sizeof(struct quadmouse_softc), quadmouseprobe, quadmouseattach sizeof(struct quadmouse_softc), quadmouseprobe, quadmouseattach
@ -195,16 +196,18 @@ quadmouseopen(dev, flag, mode, p)
if (sc->sc_state & QMOUSE_OPEN) return(EBUSY); if (sc->sc_state & QMOUSE_OPEN) return(EBUSY);
sc->proc = p; sc->sc_proc = p;
sc->lastx = -1; sc->lastx = -1;
sc->lasty = -1; sc->lasty = -1;
sc->lastb = -1; sc->lastb = -1;
/* initialise buffer */ /* initialise buffer */
if (clalloc(&sc->buffer, QMOUSE_BSIZE, 0) == -1) if (clalloc(&sc->sc_buffer, QMOUSE_BSIZE, 0) == -1)
return(ENOMEM); return(ENOMEM);
sc->mode = MOUSEMODE_ABS;
sc->sc_state |= QMOUSE_OPEN; sc->sc_state |= QMOUSE_OPEN;
if (sc->sc_irqnum == IRQ_TIMER1) { if (sc->sc_irqnum == IRQ_TIMER1) {
@ -233,10 +236,10 @@ quadmouseclose(dev, flag, mode, p)
if (irq_release(sc->sc_irqnum, &sc->sc_ih) != 0) if (irq_release(sc->sc_irqnum, &sc->sc_ih) != 0)
panic("Cannot release IRQ %d\n", sc->sc_irqnum); panic("Cannot release IRQ %d\n", sc->sc_irqnum);
sc->proc = NULL; sc->sc_proc = NULL;
sc->sc_state = 0; sc->sc_state = 0;
clfree(&sc->buffer); clfree(&sc->sc_buffer);
return(0); return(0);
} }
@ -256,7 +259,7 @@ quadmouseread(dev, uio, flag)
error = 0; error = 0;
s=spltty(); s=spltty();
while(sc->buffer.c_cc==0) { while(sc->sc_buffer.c_cc==0) {
if(flag & IO_NDELAY) { if(flag & IO_NDELAY) {
(void)splx(s); (void)splx(s);
return(EWOULDBLOCK); return(EWOULDBLOCK);
@ -269,12 +272,12 @@ quadmouseread(dev, uio, flag)
} }
} }
while(sc->buffer.c_cc>0 && uio->uio_resid>0) { while(sc->sc_buffer.c_cc>0 && uio->uio_resid>0) {
length=min(sc->buffer.c_cc, uio->uio_resid); length=min(sc->sc_buffer.c_cc, uio->uio_resid);
if(length>sizeof(buffer)) if(length>sizeof(buffer))
length=sizeof(buffer); length=sizeof(buffer);
(void) q_to_b(&sc->buffer, buffer, length); (void) q_to_b(&sc->sc_buffer, buffer, length);
if ((error = (uiomove(buffer, length, uio)))) if ((error = (uiomove(buffer, length, uio))))
break; break;
@ -327,29 +330,77 @@ quadmouseioctl(dev, cmd, data, flag, p)
register struct mouse_state *co = (void *)data; register struct mouse_state *co = (void *)data;
WriteWord(IOMD_MOUSEX, co->x); WriteWord(IOMD_MOUSEX, co->x);
WriteWord(IOMD_MOUSEY, co->y); WriteWord(IOMD_MOUSEY, co->y);
/* Silly, but here for completeness, just incase */
/* the hardware supports it *giggle* */
/* This is not writable -- mark -- technically this should fault */
/* WriteWord ( IO_MOUSE_BUTTONS, co->buttons );*/
return 0; return 0;
} }
case MOUSEIOC_SETBOUNDS: case MOUSEIOC_SETBOUNDS:
{ {
register struct mouse_boundingbox *bo = (void *)data; register struct mouse_boundingbox *bo = (void *)data;
sc->boundx = bo->x; sc->boundy = bo->y; struct mousebufrec buffer;
sc->bounda = bo->a; sc->boundb = bo->b; int s;
#ifdef MOUSE_IOC_ACK
s = spltty();
#endif
sc->boundx = bo->x;
sc->boundy = bo->y;
sc->bounda = bo->a;
sc->boundb = bo->b;
buffer.status = IOC_ACK;
buffer.x = sc->origx;
buffer.y = sc->origy;
#ifdef MOUSE_IOC_ACK
if (sc->sc_buffer.c_cc > 0)
printf("qms: setting bounding with non empty buffer (%d)\n", sc->sc_buffer.c_cc);
quadmouseputbuffer(sc, &buffer);
(void)splx(s);
#endif
return 0;
}
case MOUSEIOC_SETMODE:
{
struct mousebufrec buffer;
int s;
#ifdef MOUSE_IOC_ACK
s = spltty();
#endif
sc->mode = *(u_int *)data;
buffer.status = IOC_ACK;
buffer.x = sc->origx;
buffer.y = sc->origy;
#ifdef MOUSE_IOC_ACK
if (sc->sc_buffer.c_cc > 0)
printf("qms: setting mode with non empty buffer (%d)\n", sc->sc_buffer.c_cc);
quadmouseputbuffer(sc, &buffer);
(void)splx(s);
#endif
return 0; return 0;
} }
case MOUSEIOC_SETORIGIN: case MOUSEIOC_SETORIGIN:
{ {
register struct mouse_origin *oo = (void *)data; register struct mouse_origin *oo = (void *)data;
/* int oldx, oldy;*/ struct mousebufrec buffer;
int s;
#ifdef MOUSE_IOC_ACK
s = spltty();
#endif
/* Need to fix up! */ /* Need to fix up! */
sc->origx = oo->x; sc->origx = oo->x;
sc->origy = oo->y; sc->origy = oo->y;
buffer.status = IOC_ACK;
buffer.x = sc->origx;
buffer.y = sc->origy;
#ifdef MOUSE_IOC_ACK
if (sc->sc_buffer.c_cc > 0)
printf("qms: setting origin with non empty buffer (%d)\n", sc->sc_buffer.c_cc);
quadmouseputbuffer(sc, &buffer);
(void)splx(s);
#endif
return 0; return 0;
} }
case MOUSEIOC_GETSTATE: case MOUSEIOC_GETSTATE:
@ -396,16 +447,21 @@ quadmouseintr(sc)
b >>= 4; b >>= 4;
if (x != sc->lastx || y != sc->lasty || b != sc->lastb) { if (x != sc->lastx || y != sc->lasty || b != sc->lastb) {
/* Mouse state changed */ /* Mouse state changed */
buffer.status = b | ( b ^ sc->lastb) << 3 | (((x==sc->lastx) && (y==sc->lasty))?0:0x40); buffer.status = b | ( b ^ sc->lastb) << 3 | (((x==sc->lastx) && (y==sc->lasty))?0:MOVEMENT);
if((sc->mode & MOUSEMODE_REL) == MOUSEMODE_REL) {
sc->origx = sc->origy = 0;
WriteWord(IOMD_MOUSEX, sc->origx);
WriteWord(IOMD_MOUSEY, sc->origy);
}
buffer.x = x; buffer.x = x;
buffer.y = y; buffer.y = y;
microtime(&buffer.event_time); microtime(&buffer.event_time);
if(sc->buffer.c_cc==0) if(sc->sc_buffer.c_cc==0)
dosignal=1; dosignal=1;
s=spltty(); s=spltty();
(void) b_to_q((char *)&buffer, sizeof(buffer), &sc->buffer); (void) b_to_q((char *)&buffer, sizeof(buffer), &sc->sc_buffer);
(void)splx(s); (void)splx(s);
selwakeup(&sc->sc_rsel); selwakeup(&sc->sc_rsel);
@ -415,7 +471,7 @@ quadmouseintr(sc)
} }
if(dosignal) if(dosignal)
psignal(sc->proc, SIGIO); psignal(sc->sc_proc, SIGIO);
sc->lastx = x; sc->lastx = x;
sc->lasty = y; sc->lasty = y;
@ -426,6 +482,7 @@ quadmouseintr(sc)
return(0); /* Pass interrupt on down the chain */ return(0); /* Pass interrupt on down the chain */
} }
#if 0
int int
quadmouseselect(dev, rw, p) quadmouseselect(dev, rw, p)
dev_t dev; dev_t dev;
@ -440,7 +497,7 @@ quadmouseselect(dev, rw, p)
return 0; return 0;
s=spltty(); s=spltty();
if(sc->buffer.c_cc > 0) { if(sc->sc_buffer.c_cc > 0) {
selrecord(p, &sc->sc_rsel); selrecord(p, &sc->sc_rsel);
(void)splx(s); (void)splx(s);
return 0; return 0;
@ -449,4 +506,56 @@ quadmouseselect(dev, rw, p)
return 1; return 1;
} }
#else
int
quadmousepoll(dev, events, p)
dev_t dev;
int events;
struct proc *p;
{
struct quadmouse_softc *sc = quadmouse_cd.cd_devs[minor(dev)];
int revents = 0;
int s = spltty();
if (events & (POLLIN | POLLRDNORM))
if (sc->sc_buffer.c_cc > 0)
revents |= events & (POLLIN | POLLRDNORM);
else
selrecord(p, &sc->sc_rsel);
splx(s);
return (revents);
}
#endif
void
quadmouseputbuffer(sc, buffer)
struct quadmouse_softc *sc;
struct mousebufrec *buffer;
{
int s;
int dosignal=0;
/* Time stamp the buffer */
microtime(&buffer->event_time);
if(sc->sc_buffer.c_cc==0)
dosignal=1;
s=spltty();
(void) b_to_q((char *)buffer, sizeof(*buffer), &sc->sc_buffer);
(void)splx(s);
selwakeup(&sc->sc_rsel);
if(sc->sc_state & QMOUSE_ASLEEP) {
sc->sc_state &= ~QMOUSE_ASLEEP;
wakeup((caddr_t)sc);
}
if(dosignal)
psignal(sc->sc_proc, SIGIO);
}
/* End of quadmouse.c */ /* End of quadmouse.c */