From 674af24da0ced3821a25d87329fc49f36b4b9b6e Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 6 Oct 1993 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1993-10-06 --- carrera/dat.h | 17 -- carrera/screen.c | 18 +- carrera/trap.c | 2 +- port/devcons.c | 3 - port/devmnt.c | 8 +- port/devmouse.c | 520 +++++++++++++++++++++++++++++++++++++++++++++++ port/error.h | 6 +- 7 files changed, 529 insertions(+), 45 deletions(-) create mode 100644 port/devmouse.c diff --git a/carrera/dat.h b/carrera/dat.h index 1fbc3353b6a7a3077f49bb21421dca019388a581..5630ba3db1a5fc0c82d26405acee32d2a8d7172a 100644 --- a/carrera/dat.h +++ b/carrera/dat.h @@ -1,6 +1,5 @@ typedef struct Conf Conf; typedef struct FPsave FPsave; -typedef struct Cycmsg Cycmsg; typedef struct KMap KMap; typedef struct Lance Lance; typedef struct Lancemem Lancemem; @@ -77,26 +76,10 @@ struct FPsave struct PMMU { int pidonmach[MAXMACH]; - /* - * I/O point for hotrod interfaces. - * This is the easiest way to allocate - * them, but not the prettiest or most general. - */ - Cycmsg *kcyc; - Cycmsg *ucyc; - Cycmsg *fcyc; }; #include "../port/portdat.h" -struct Cycmsg -{ - ulong cmd; - ulong param[5]; - Rendez r; - uchar intr; /* flag: interrupt has occurred */ -}; - /* First FOUR members offsets known by l.s */ struct Mach { diff --git a/carrera/screen.c b/carrera/screen.c index a289c6ae2f5ce8afd937dc269670b700a94f264d..0da6a4a211b2787f267489fdf230611cf0bf7ba9 100644 --- a/carrera/screen.c +++ b/carrera/screen.c @@ -112,22 +112,6 @@ GBitmap vgascreen = 0 }; -uchar bdata[] = -{ - 0xC0, -}; - -GBitmap bgrnd = -{ - (ulong*)bdata, - 0, - 4, - 3, - { 0, 0, 1, 1 }, - { 0, 0, 1, 1 }, - 0 -}; - static Rectangle window; static Point cursor; static int h, w; @@ -140,7 +124,7 @@ static int isscroll; void screenwin(void) { - gtexture(&gscreen, gscreen.r, &bgrnd, S); + memset(gscreen.base, 0xC0, gscreen.width*sizeof(ulong)*Dy(gscreen.r)); w = defont0.info[' '].width; h = defont0.height; defont = &defont0; diff --git a/carrera/trap.c b/carrera/trap.c index 99fea108adc03fd8b475cbd3ee01fafbe4966cb5..251a185e1391b78a72cb04df1d1264eb82135833 100644 --- a/carrera/trap.c +++ b/carrera/trap.c @@ -471,7 +471,7 @@ notify(Ureg *ur) *(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */ up->svr1 = ur->r1; /* save away r1 */ ur->r1 = (ulong)up->ureg; /* arg 1 is ureg* */ - *(ulong*)(sp+1*BY2WD) = (ulong)u->ureg; /* arg 1 0(FP) is ureg* */ + *(ulong*)(sp+1*BY2WD) = (ulong)up->ureg; /* arg 1 0(FP) is ureg* */ *(ulong*)(sp+0*BY2WD) = 0; /* arg 0 is pc */ ur->usp = sp; ur->pc = (ulong)up->notify; diff --git a/port/devcons.c b/port/devcons.c index 68837cf7990698ce125a4d1435dfda2e4dda3d75..4ece57cee9260bfae413b399e5faff18e59801bc 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -185,9 +185,6 @@ echo(Rune r, char *buf, int n) xsummary(); ixsummary(); break; - case 'b': - bitdebug(); - break; case 'd': consdebug(); return; diff --git a/port/devmnt.c b/port/devmnt.c index 1860824e9f66872d84bed344941ef123d904dc9a..eedc73fca4c09a681e2762b0c7bd831c9db7f55c 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -635,8 +635,9 @@ mountio(Mnt *m, Mntrpc *r) void mntrpcread(Mnt *m, Mntrpc *r) { - int n; + int n, zrd; + zrd = 0; for(;;) { if(waserror()) { if(mntflush(m, r) == 0) { @@ -650,8 +651,11 @@ mntrpcread(Mnt *m, Mntrpc *r) r->reply.tag = 0; n = (*devtab[m->c->type].read)(m->c, r->rpc, MAXRPC, 0); poperror(); - if(n == 0) + if(n == 0) { + if(++zrd > 3) + error(Ehungup); continue; + } if(convM2S(r->rpc, &r->reply, n) != 0) return; diff --git a/port/devmouse.c b/port/devmouse.c new file mode 100644 index 0000000000000000000000000000000000000000..fb122674f69a0ae0c9414ff0136e38b5154e0760 --- /dev/null +++ b/port/devmouse.c @@ -0,0 +1,520 @@ +#include "u.h" +#include "../port/lib.h" +#include +#include +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "../port/error.h" + +#include "devtab.h" + +/* + * Some monochrome screens are reversed from what we like: + * We want 0's bright and 1's dark. + * Indexed by an Fcode, these compensate for the source bitmap being wrong + * (exchange S rows) and destination (exchange D columns and invert result) + */ +int flipS[] = { + 0x0, 0x4, 0x8, 0xC, 0x1, 0x5, 0x9, 0xD, + 0x2, 0x6, 0xA, 0xE, 0x3, 0x7, 0xB, 0xF +}; + +int flipD[] = { + 0xF, 0xD, 0xE, 0xC, 0x7, 0x5, 0x6, 0x4, + 0xB, 0x9, 0xA, 0x8, 0x3, 0x1, 0x2, 0x0, +}; + +int flipping; /* are flip tables being used to transform Fcodes? */ + +typedef struct Mouseinfo Mouseinfo; +typedef struct Cursorinfo Cursorinfo; + +struct Mouseinfo +{ + /* + * First three fields are known in some l.s's + */ + int dx; + int dy; + int track; /* l.s has updated dx & dy */ + Mouse; + int redraw; /* update cursor on screen */ + ulong counter; /* increments every update */ + ulong lastcounter; /* value when /dev/mouse read */ + Rendez r; + Ref; + QLock; + int open; +}; + +struct Cursorinfo +{ + Cursor; + Lock; + int visible; /* on screen */ + int disable; /* from being used */ + Rectangle r; /* location */ +}; + +Mouseinfo mouse; +Cursorinfo cursor; +int mouseshifted; +int mousetype; +int hwcurs; + +Cursor arrow = +{ + {-1, -1}, + {0xFF, 0xE0, 0xFF, 0xE0, 0xFF, 0xC0, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x80, 0xFF, 0xC0, 0xFF, 0xE0, + 0xE7, 0xF0, 0xE3, 0xF8, 0xC1, 0xFC, 0x00, 0xFE, + 0x00, 0x7F, 0x00, 0x3E, 0x00, 0x1C, 0x00, 0x08, + }, + {0x00, 0x00, 0x7F, 0xC0, 0x7F, 0x00, 0x7C, 0x00, + 0x7E, 0x00, 0x7F, 0x00, 0x6F, 0x80, 0x67, 0xC0, + 0x43, 0xE0, 0x41, 0xF0, 0x00, 0xF8, 0x00, 0x7C, + 0x00, 0x3E, 0x00, 0x1C, 0x00, 0x08, 0x00, 0x00, + } +}; + +ulong setbits[16]; +GBitmap set = +{ + setbits, + 0, + 1, + 0, + {0, 0, 16, 16}, + {0, 0, 16, 16} +}; + +ulong clrbits[16]; +GBitmap clr = +{ + clrbits, + 0, + 1, + 0, + {0, 0, 16, 16}, + {0, 0, 16, 16} +}; + +ulong cursorbackbits[16*4]; +GBitmap cursorback = +{ + cursorbackbits, + 0, + 1, + 0, + {0, 0, 16, 16}, + {0, 0, 16, 16} +}; + +void Cursortocursor(Cursor*); +int mousechanged(void*); + +enum{ + Qdir, + Qmouse, + Qmousectl, +}; + +Dirtab mousedir[]={ + "mouse", {Qmouse}, 0, 0666, + "mousectl", {Qmousectl}, 0, 0220, +}; + +#define NMOUSE (sizeof(mousedir)/sizeof(Dirtab)) + +extern GBitmap gscreen; + +void +mousereset(void) +{ + ulong r; + + if(!conf.monitor) + return; + + getcolor(0, &r, &r, &r); + if(r == 0) + flipping = 1; + flipping = 0; /* howard, why is this necessary to get a black arrow on carrera? */ + Cursortocursor(&arrow); +} + +void +mouseinit(void) +{ + if(!conf.monitor) + return; + if(gscreen.ldepth > 3) + cursorback.ldepth = 0; + else{ + cursorback.ldepth = gscreen.ldepth; + cursorback.width = ((16 << gscreen.ldepth) + 31) >> 5; + } + cursoron(1); +} + +Chan* +mouseattach(char *spec) +{ + if(!conf.monitor) + error(Egreg); + return devattach('m', spec); +} + +Chan* +mouseclone(Chan *c, Chan *nc) +{ + nc = devclone(c, nc); + if(c->qid.path != CHDIR) + incref(&mouse); + return nc; +} + +int +mousewalk(Chan *c, char *name) +{ + return devwalk(c, name, mousedir, NMOUSE, devgen); +} + +void +mousestat(Chan *c, char *db) +{ + devstat(c, db, mousedir, NMOUSE, devgen); +} + +Chan* +mouseopen(Chan *c, int omode) +{ + switch(c->qid.path){ + case CHDIR: + if(omode != OREAD) + error(Eperm); + break; + case Qmouse: + lock(&mouse); + if(mouse.open){ + unlock(&mouse); + error(Einuse); + } + mouse.open = 1; + mouse.ref++; + unlock(&mouse); + break; + default: + incref(&mouse); + } + c->mode = openmode(omode); + c->flag |= COPEN; + c->offset = 0; + return c; +} + +void +mousecreate(Chan *c, char *name, int omode, ulong perm) +{ + if(!conf.monitor) + error(Egreg); + USED(c, name, omode, perm); + error(Eperm); +} + +void +mouseremove(Chan *c) +{ + USED(c); + error(Eperm); +} + +void +mousewstat(Chan *c, char *db) +{ + USED(c, db); + error(Eperm); +} + +void +mouseclose(Chan *c) +{ + if(c->qid.path!=CHDIR && (c->flag&COPEN)){ + lock(&mouse); + if(c->qid.path == Qmouse) + mouse.open = 0; + unlock(&mouse); + } +} + +long +mouseread(Chan *c, void *va, long n, ulong offset) +{ + uchar *p; + + USED(offset); + if(c->qid.path & CHDIR) + return devdirread(c, va, n, mousedir, NMOUSE, devgen); + + if(c->qid.path == Qmouse){ + /* + * mouse: + * 'm' 1 + * buttons 1 + * point 8 + * msec 4 + */ + if(n < 14) + error(Eshort); + while(mousechanged(0) == 0) + sleep(&mouse.r, mousechanged, 0); + lock(&cursor); + p = va; + p[0] = 'm'; + p[1] = mouse.buttons; + BPLONG(p+2, mouse.xy.x); + BPLONG(p+6, mouse.xy.y); + BPLONG(p+10, TK2MS(MACHP(0)->ticks)); + mouse.lastcounter = mouse.counter; + unlock(&cursor); + return 14; + } + return 0; +} + +long +mousewrite(Chan *c, void *va, long n, ulong offset) +{ + uchar *p; + Point pt; + char buf[64]; + + USED(offset); + + switch(c->qid.path){ + case CHDIR: + error(Eisdir); + + case Qmousectl: + if(n >= sizeof(buf)) + n = sizeof(buf)-1; + strncpy(buf, va, n); + buf[n] = 0; + mousectl(buf); + return n; + + case Qmouse: + if(n != 9) + error(Eshort); + qlock(&mouse); + p = va; + pt.x = BGLONG(p+1); + pt.y = BGLONG(p+5); + if(ptinrect(pt, gscreen.r)){ + mouse.xy = pt; + mouse.redraw = 1; + mouse.track = 1; + mouseclock(); + } + qunlock(&mouse); + return n; + } + + error(Egreg); + return -1; +} + +void +Cursortocursor(Cursor *c) +{ + int i; + uchar *p; + + lock(&cursor); + memmove(&cursor, c, sizeof(Cursor)); + for(i=0; i<16; i++){ + p = (uchar*)&setbits[i]; + *p = c->set[2*i]; + *(p+1) = c->set[2*i+1]; + p = (uchar*)&clrbits[i]; + *p = c->clr[2*i]; + *(p+1) = c->clr[2*i+1]; + } + if(hwcurs) + hwcursset(set.base, clr.base, cursor.offset.x, cursor.offset.y); + unlock(&cursor); +} + +void +cursoron(int dolock) +{ + if(cursor.disable) + return; + if(dolock) + lock(&cursor); + if(cursor.visible++ == 0){ + if(hwcurs) + hwcursmove(mouse.xy.x, mouse.xy.y); + else { + cursor.r.min = mouse.xy; + cursor.r.max = add(mouse.xy, Pt(16, 16)); + cursor.r = raddp(cursor.r, cursor.offset); + gbitblt(&cursorback, Pt(0, 0), &gscreen, cursor.r, S); + gbitblt(&gscreen, cursor.r.min, + &clr, Rect(0, 0, 16, 16), flipping? flipD[D&~S] : D&~S); + gbitblt(&gscreen, cursor.r.min, + &set, Rect(0, 0, 16, 16), flipping? flipD[S|D] : S|D); + mbbrect(cursor.r); + } + } + if(dolock) + unlock(&cursor); +} + +void +cursoroff(int dolock) +{ + if(cursor.disable) + return; + if(dolock) + lock(&cursor); + if(--cursor.visible == 0) { + if(!hwcurs) { + gbitblt(&gscreen, cursor.r.min, &cursorback, Rect(0, 0, 16, 16), S); + mbbrect(cursor.r); + mousescreenupdate(); + } + } + if(dolock) + unlock(&cursor); +} + +/* + * called by the clock routine to redraw the cursor + */ +void +mouseclock(void) +{ + if(mouse.track){ + mousetrack(mouse.buttons, mouse.dx, mouse.dy); + mouse.track = 0; + mouse.dx = 0; + mouse.dy = 0; + } + if(mouse.redraw && canlock(&cursor)){ + mouse.redraw = 0; + cursoroff(0); + cursoron(0); + mousescreenupdate(); + unlock(&cursor); + } +} + +/* + * called at interrupt level to update the structure and + * awaken any waiting procs. + */ +void +mousetrack(int b, int dx, int dy) +{ + int x, y; + + x = mouse.xy.x + dx; + if(x < gscreen.r.min.x) + x = gscreen.r.min.x; + if(x >= gscreen.r.max.x) + x = gscreen.r.max.x; + y = mouse.xy.y + dy; + if(y < gscreen.r.min.y) + y = gscreen.r.min.y; + if(y >= gscreen.r.max.y) + y = gscreen.r.max.y; + mouse.counter++; + mouse.xy = Pt(x, y); + mouse.buttons = b; + mouse.redraw = 1; + wakeup(&mouse.r); +} + +/* + * 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 & right button is the same as middle button (for 2 button mice) + */ +int +m3mouseputc(IOQ *q, int c) +{ + static uchar msg[3]; + static int nb; + static int middle; + static uchar b[] = { 0, 4, 1, 5, 0, 2, 1, 5 }; + short x; + int dx, dy, newbuttons; + + USED(q); + /* + * check bit 6 for consistency + */ + if(nb==0){ + if((c&0x40) == 0){ + /* an extra byte gets sent for the middle button */ + middle = (c&0x20) ? 2 : 0; + newbuttons = (mouse.buttons & ~2) | middle; + mousetrack(newbuttons, 0, 0); + return 0; + } + } + msg[nb] = c; + if(++nb == 3){ + nb = 0; + newbuttons = middle | b[(msg[0]>>4)&3 | (mouseshifted ? 4 : 0)]; + x = (msg[0]&0x3)<<14; + dx = (x>>8) | msg[1]; + x = (msg[0]&0xc)<<12; + dy = (x>>8) | msg[2]; + mousetrack(newbuttons, dx, dy); + } + return 0; +} + +/* + * Logitech 5 byte packed binary mouse format, 8 bit bytes + * + * shift & right button is the same as middle button (for 2 button mice) + */ +int +mouseputc(IOQ *q, int c) +{ + static short msg[5]; + static int nb; + static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7, 0, 2, 2, 6, 1, 5, 3, 7}; + int dx, dy, newbuttons; + + USED(q); + if((c&0xF0) == 0x80) + nb=0; + msg[nb] = c; + if(c & 0x80) + msg[nb] |= ~0xFF; /* sign extend */ + if(++nb == 5){ + newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)]; + dx = msg[1]+msg[3]; + dy = -(msg[2]+msg[4]); + mousetrack(newbuttons, dx, dy); + nb = 0; + } + return 0; +} + +int +mousechanged(void *m) +{ + USED(m); + return mouse.lastcounter - mouse.counter; +} diff --git a/port/error.h b/port/error.h index f9625e127fe85f1011ef98577b19c7f59379bdd7..032c4253c2b745bb4484c68ac6b2483f265c8c51 100644 --- a/port/error.h +++ b/port/error.h @@ -18,11 +18,6 @@ extern char Einuse[]; /* device or object already in use */ extern char Eio[]; /* i/o error */ extern char Etoobig[]; /* read or write too large */ extern char Etoosmall[]; /* read or write too small */ -extern char Ebadblt[]; /* bad bitblt or bitmap request */ -extern char Ebadbitmap[]; /* unallocated bitmap */ -extern char Enobitmap[]; /* out of bitmap descriptors */ -extern char Enobitstore[]; /* out of bitmap storage */ -extern char Ebadfont[]; /* unallocated font */ extern char Enetaddr[]; /* bad network address */ extern char Emsgsize[]; /* message is too big for protocol */ extern char Enetbusy[]; /* network device is busy or allocated */ @@ -55,4 +50,5 @@ extern char Esfnotcached[]; /* subfont not cached */ extern char Esoverlap[]; /* segments overlap */ extern char Emouseset[]; /* mouse type already set */ extern char Erecover[]; /* failed to recover fd */ +extern char Eshort[]; /* i/o count too small */ extern char Egreg[]; /* coherency problem */