M pc/devconfig.c => pc/devconfig.c +4 -10
@@ 190,16 190,10 @@ configwrite(Chan *c, void *buf, long n, ulong offset)
n = sizeof(cbuf) - 1;
memmove(cbuf, buf, n);
cbuf[n] = 0;
- if(strncmp("accelerated", cbuf, 11) == 0)
- mouseaccelerate(1);
- else if(strncmp("linear", cbuf, 6) == 0)
- mouseaccelerate(0);
- else if(strncmp("serial", cbuf, 6) == 0)
- mouseserial(atoi(cbuf+6));
- else if(strncmp("ps2", cbuf, 3) == 0)
- mouseps2();
- else if(strncmp("resolution", cbuf, 10) == 0)
- mouseres(atoi(cbuf+10));
+ cp = strchr(cbuf, '\n');
+ if(cp)
+ *cp = 0;
+ mousectl(cbuf);
return n;
}
error(Eperm);
M pc/devuart.c => pc/devuart.c +16 -14
@@ 63,7 63,7 @@ struct Uart
int enabled;
/* console interface */
- int nostream; /* can't use the stream interface */
+ int special; /* can't use the stream interface */
IOQ *iq; /* input character queue */
IOQ *oq; /* output character queue */
@@ 234,9 234,6 @@ uartsetup(void)
uartwrreg(up, Format, 0);
up->sticky[Mctl] |= Inton;
uartwrreg(up, Mctl, 0x0);
-
- uartdtr(up, 1);
- uartrts(up, 1);
}
}
@@ 409,10 406,16 @@ uartdisable(Uart *up)
uartwrreg(up, Iena, 0);
/*
+ * revert to default settings
+ */
+ up->sticky[Format] = Bits8;
+ uartwrreg(up, Format, 0);
+
+ /*
* turn off DTR and RTS
+ */
uartdtr(up, 0);
uartrts(up, 0);
- */
up->enabled = 0;
/*
@@ 425,11 428,6 @@ uartdisable(Uart *up)
if(modem(0) < 0)
print("can't turn off modem speaker\n");
}
-
- /*
- * slow the clock down again
- */
- clockinit();
}
/*
@@ 441,11 439,12 @@ uartspecial(int port, IOQ *oq, IOQ *iq, int baud)
Uart *up = &uart[port];
uartsetup();
- up->nostream = 1;
+ up->special = 1;
up->oq = oq;
up->iq = iq;
uartenable(up);
- uartsetbaud(up, baud);
+ if(baud)
+ uartsetbaud(up, baud);
if(iq){
/*
@@ 498,6 497,9 @@ uartstclose(Queue *q)
{
Uart *up = q->ptr;
+ if(up->special)
+ return;
+
uartdisable(up);
qlock(up);
@@ 644,7 646,7 @@ uartreset(void)
uartsetup();
for(up = uart; up < &uart[2]; up++){
- if(up->nostream)
+ if(up->special)
continue;
up->iq = xalloc(sizeof(IOQ));
initq(up->iq);
@@ 711,7 713,7 @@ uartopen(Chan *c, int omode)
break;
}
- if(up && up->nostream)
+ if(up && up->special)
error(Einuse);
if((c->qid.path & CHDIR) == 0)
M pc/fns.h => pc/fns.h +1 -5
@@ 37,11 37,7 @@ void kbdinit(void);
void mathinit(void);
void mmuinit(void);
int modem(int);
-void mouseserial(int);
-void mouseps2(void);
-void mouseaccelerate(int);
-void mouseres(int);
-void mousespeed(int);
+void mousectl(char*);
uchar nvramread(int);
void outb(int, int);
void outs(int, ushort);
M pc/kbd.c => pc/kbd.c +133 -65
@@ 4,6 4,7 @@
#include "dat.h"
#include "fns.h"
#include "io.h"
+#include "../port/error.h"
#include <libg.h>
#include <gnot.h>
@@ 49,6 50,10 @@ enum {
Pgdown= View,
Ins= KF|20,
Del= 0x7F,
+
+ Rbutton=4,
+ Mbutton=2,
+ Lbutton=1,
};
uchar kbtab[] =
@@ 107,11 112,10 @@ KIOQ kbdq;
static int mousebuttons;
static int keybuttons;
static uchar ccc;
+static int mousetype;
+static int mouseport;
+static int shift;
-/*
- * predeclared
- */
-static void kbdintr(Ureg*);
enum
{
@@ 128,9 132,10 @@ enum
Mouseserial= 1,
MousePS2= 2,
};
-static int mousetype;
-static int mymouseputc(IOQ*, int);
+static void kbdintr(Ureg*);
+static int ps2mouseputc(IOQ*, int);
+static int m3mouseputc(IOQ*, int);
/*
* wait for output no longer busy
@@ 238,6 243,7 @@ kbdinit(void)
int c;
setvec(Kbdvec, kbdintr);
+ bigcursor();
/* wait for a quiescent controller */
while((c = inb(Status)) & (Outbusy | Inready))
@@ 267,29 273,33 @@ kbdinit(void)
/*
* setup a serial mouse
*/
-void
-mouseserial(int port)
+static void
+serialmouse(int port, char *type, int setspeed)
{
if(mousetype)
- return;
+ error(Emouseset);
/* set up /dev/eia0 as the mouse */
- uartspecial(port, 0, &mouseq, 1200);
+ uartspecial(port, 0, &mouseq, setspeed ? 1200 : 0);
+ if(type && *type == 'M')
+ mouseq.putc = m3mouseputc;
+ mouseport = port;
mousetype = Mouseserial;
}
/*
* set up a ps2 mouse
*/
-void
-mouseps2(void)
+static void
+ps2mouse(void)
{
int x;
- bigcursor();
- setvec(Mousevec, kbdintr);
+ if(mousetype)
+ error(Emouseset);
/* enable kbd/mouse xfers and interrupts */
+ setvec(Mousevec, kbdintr);
x = splhi();
ccc &= ~Cmousedis;
ccc |= Cmouseint;
@@ 306,7 316,7 @@ mouseps2(void)
print("mouse init failed\n");
/* make mouse streaming, enabled */
- mousecmd(0xF6);
+ mousecmd(0xEA);
mousecmd(0xF4);
splx(x);
@@ 314,47 324,7 @@ mouseps2(void)
}
/*
- * turn mouse acceleration on/off
- */
-void
-mouseaccelerate(int on)
-{
- int x;
-
- switch(mousetype){
- case MousePS2:
- x = splhi();
- if(on)
- mousecmd(0xE7);
- else
- mousecmd(0xE6);
- splx(x);
- break;
- }
-}
-
-/*
- * set mouse resolution
- */
-void
-mouseres(int res)
-{
- int x;
-
- switch(mousetype){
- case MousePS2:
- x = splhi();
- mousecmd(0xE8);
- mousecmd(res);
- splx(x);
- break;
- }
-}
-
-static int shift;
-
-/*
- * mouse message is three bytes
+ * ps/2 mouse message is three bytes
*
* byte 0 - 0 0 SDY SDX 1 M R L
* byte 1 - DX
@@ 363,12 333,11 @@ static int shift;
* shift & left button is the same as middle button
*/
static int
-mymouseputc(IOQ *q, int c)
+ps2mouseputc(IOQ *q, int c)
{
static short msg[3];
static int nb;
static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 5, 2, 3, 6, 7 };
- static lastdx, lastdy;
extern Mouseinfo mouse;
USED(q); /* not */
@@ 398,6 367,105 @@ mymouseputc(IOQ *q, int c)
}
/*
+ * microsoft 3 button, 7 bit bytes
+ *
+ * byte 0 - 1 L R Y7 Y6 X7 X6
+ * byte 1 - 0 X5 X4 X3 X2 X1 X0
+ * byte 2 - 0 Y5 Y4 Y3 Y2 Y1 Y0
+ * byte 3 - 0 M x x x x x (optional)
+ *
+ * shift & left button is the same as middle button (for 2 button mice)
+ */
+static int
+m3mouseputc(IOQ *q, int c)
+{
+ static uchar msg[3];
+ static int nb;
+ static uchar b[] = { 0, 4, 1, 5, 0, 4, 3, 7 };
+ extern Mouseinfo mouse;
+
+ USED(q); /* not */
+
+ /*
+ * check bit 6 for consistency
+ */
+ if(nb==0){
+ if((c&0x40) != 0){
+ /* must be 4th (M button) byte */
+ mousebuttons = (mousebuttons & ~Mbutton) | ((c&0x2)?Mbutton:0);
+ mouse.newbuttons = mousebuttons | keybuttons;
+ mouse.dx = 0;
+ mouse.dy = 0;
+ mouse.track = 0;
+ mouseclock();
+ return 0;
+ }
+ }
+ msg[nb] = c;
+ if(++nb == 3){
+ nb = 0;
+ mousebuttons = b[(msg[0]>>4)&3 | (shift ? 4 : 0)];
+ mouse.newbuttons = mousebuttons | keybuttons;
+ mouse.dx = (((msg[0]&3)<<7) | msg[1]) - 128;
+ mouse.dy = (((msg[0]&0xc)<<5) | msg[2]) - 128;
+ mouse.track = 1;
+ mouseclock();
+ }
+ return 0;
+}
+
+/*
+ * set/change mouse configuration
+ */
+void
+mousectl(char *arg)
+{
+ int n, x;
+ char *field[3];
+
+ n = getfields(arg, field, 3, ' ');
+ if(n < 1)
+ return;
+ if(strncmp(field[0], "serial", 6) == 0){
+ if(n > 1)
+ serialmouse(atoi(field[1]), field[2], 0);
+ else
+ serialmouse(atoi(field[0]+6), 0, 1);
+ } else if(strcmp(field[0], "ps2") == 0){
+ ps2mouse();
+ } else if(strcmp(field[0], "accelerated") == 0){
+ switch(mousetype){
+ case MousePS2:
+ x = splhi();
+ mousecmd(0xE7);
+ splx(x);
+ break;
+ }
+ } else if(strcmp(field[0], "linear") == 0){
+ switch(mousetype){
+ case MousePS2:
+ x = splhi();
+ mousecmd(0xE6);
+ splx(x);
+ break;
+ }
+ } else if(strcmp(field[0], "res") == 0){
+ if(n < 2)
+ n = 1;
+ else
+ n = atoi(field[1]);
+ switch(mousetype){
+ case MousePS2:
+ x = splhi();
+ mousecmd(0xE8);
+ mousecmd(n);
+ splx(x);
+ break;
+ }
+ }
+}
+
+/*
* Ctrl key used as middle button pressed
*/
static void
@@ 454,7 522,7 @@ kbdintr0(void)
* if it's the mouse...
*/
if(s & Minready){
- mymouseputc(&mouseq, c);
+ ps2mouseputc(&mouseq, c);
return 0;
}
@@ 502,13 570,13 @@ kbdintr0(void)
ctl = 0;
break;
case KF|1:
- mboff(4);
+ mboff(Rbutton);
break;
case KF|2:
- mboff(2);
+ mboff(Mbutton);
break;
case KF|3:
- mboff(1);
+ mboff(Lbutton);
break;
}
return 0;
@@ 572,13 640,13 @@ kbdintr0(void)
ctl = 1;
return 0;
case KF|1:
- mbon(4);
+ mbon(Rbutton);
return 0;
case KF|2:
- mbon(2);
+ mbon(Mbutton);
return 0;
case KF|3:
- mbon(1);
+ mbon(Lbutton);
return 0;
}
}
M port/devlance.c => port/devlance.c +2 -1
@@ 799,7 799,8 @@ isinput(void *arg)
{
Msg *m = arg;
- return l.wedged || l.self.first || ((MPus(m->flags) & LANCEOWNER)==0);
+ return ((MPus(m->flags) & LANCEOWNER)==0) || l.wedged || l.self.first
+ || l.closeline;
}
static void
M port/error.h => port/error.h +1 -0
@@ 54,3 54,4 @@ extern char Enomem[]; /* kernel allocate failed */
extern char Esfnotcached[]; /* subfont not cached */
extern char Egreg[]; /* it's a thermal problem */
extern char Esoverlap[]; /* segments overlap */
+extern char Emouseset[]; /* mouse type already set */
M port/stil.c => port/stil.c +50 -35
@@ 274,7 274,7 @@ ilrcvmsg(Ipifc *ifc, Block *bp)
Ilhdr *ih;
Ilcb *ic;
int plen, illen;
- Ipconv *s, **p, **etab, *new;
+ Ipconv *s, **p, **etab, *new, *spec, *gen;
short sp, dp;
Ipaddr dst;
@@ 315,46 315,61 @@ ilrcvmsg(Ipifc *ifc, Block *bp)
if(ih->iltype != Ilsync)
goto drop;
- /* Look for a listener */
- for(p = ifc->conv; p < etab; p++) {
+ gen = 0;
+ spec = 0;
+ etab = &ifc->conv[Nipconv];
+ for(p = ifc->conv; p < etab && *p; p++) {
s = *p;
- if(s == 0)
- break;
if(s->ilctl.state == Illistening)
if(s->pdst == 0)
if(s->dst == 0) {
- if(s->curlog > s->backlog)
- goto reset;
-
- new = ipincoming(ifc, s);
- if(new == 0)
- goto reset;
-
- new->newcon = s;
- new->ifc = s->ifc;
- new->psrc = sp;
- new->pdst = dp;
- new->dst = nhgetl(ih->src);
-
- ic = &new->ilctl;
- ic->state = Ilsyncee;
- initseq += TK2MS(MACHP(0)->ticks);
- ic->start = initseq & 0xffffff;
- ic->next = ic->start+1;
- ic->recvd = 0;
- ic->rstart = nhgetl(ih->ilid);
- ic->slowtime = Slowtime;
- ic->rtt = Iltickms;
- ic->querytime = Keepalivetime;
- ic->deathtime = Keepalivetime;
- ic->window = Defaultwin;
- ilprocess(new, ih, bp);
-
- s->curlog++;
- wakeup(&s->listenr);
- return;
+ if(s->psrc == sp){
+ spec = s;
+ break;
+ }
+ if(s->psrc == 0)
+ gen = s;
}
}
+
+ if(spec)
+ s = spec;
+ else if(gen)
+ s = gen;
+ else
+ goto drop;
+
+ if(s->curlog > s->backlog)
+ goto reset;
+
+ new = ipincoming(ifc, s);
+ if(new == 0)
+ goto reset;
+
+ new->newcon = s;
+ new->ifc = s->ifc;
+ new->psrc = sp;
+ new->pdst = dp;
+ new->dst = nhgetl(ih->src);
+
+ ic = &new->ilctl;
+ ic->state = Ilsyncee;
+ initseq += TK2MS(MACHP(0)->ticks);
+ ic->start = initseq & 0xffffff;
+ ic->next = ic->start+1;
+ ic->recvd = 0;
+ ic->rstart = nhgetl(ih->ilid);
+ ic->slowtime = Slowtime;
+ ic->rtt = Iltickms;
+ ic->querytime = Keepalivetime;
+ ic->deathtime = Keepalivetime;
+ ic->window = Defaultwin;
+ ilprocess(new, ih, bp);
+
+ s->curlog++;
+ wakeup(&s->listenr);
+ return;
+
drop:
freeb(bp);
return;