From 17887901fd4052103c5b3491dfce1dd04ff6967a Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 14 Apr 1994 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1994-04-14 --- carrera/screen.c | 60 +++++++------ carrera/screen.h | 20 +++-- pc/devvga.c | 175 ++++++++++++++++++++++++++++++++++++- pc/screen.h | 20 +++++ port/devmouse.c | 218 ++--------------------------------------------- port/portfns.h | 5 +- 6 files changed, 252 insertions(+), 246 deletions(-) create mode 100644 pc/screen.h diff --git a/carrera/screen.c b/carrera/screen.c index 79ef3add43e12b35239230f74d6201b47907b4ec..0bc520d91b70c80bcbe28463aa10dba5833f3323 100644 --- a/carrera/screen.c +++ b/carrera/screen.c @@ -93,7 +93,7 @@ Cursor fatarrow = { }; static Rectangle window; -static Point cursor; +static Point curpos; static int h, w; extern Cursor arrow; @@ -126,10 +126,9 @@ screenwin(void) p = add(window.min, Pt(10, 2)); subfstring(&gscreen, p, &defont0, "Brazil Console ", S); window.min.y += h+6; - cursor = window.min; + curpos = window.min; window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; - hwcurs = 1; d = DAC; /* cursor color 1: white */ d->cr1 = 0x01; @@ -151,7 +150,7 @@ screenwin(void) d->cr2 = 0; /* initialize with all-transparent cursor */ memset(zbuf, 0, sizeof zbuf); - hwcursset(zbuf, zbuf, 0, 0); + setcursor(zbuf, zbuf, 0, 0); /* enable both planes of cursor */ d->cr1 = 0x03; d->cr0 = 0x00; @@ -252,7 +251,7 @@ scroll(void) bitblt(&gscreen, window.min, &gscreen, r, S); r = Rpt(Pt(window.min.x, window.max.y-o), window.max); bitblt(&gscreen, r.min, &gscreen, r, Zero); - cursor.y -= o; + curpos.y -= o; } static void @@ -263,33 +262,33 @@ screenputc(char *buf) switch(buf[0]) { case '\n': - if(cursor.y+h >= window.max.y) + if(curpos.y+h >= window.max.y) scroll(); - cursor.y += h; + curpos.y += h; screenputc("\r"); break; case '\r': - cursor.x = window.min.x; + curpos.x = window.min.x; break; case '\t': - pos = (cursor.x-window.min.x)/w; + pos = (curpos.x-window.min.x)/w; pos = 8-(pos%8); - cursor.x += pos*w; + curpos.x += pos*w; break; case '\b': - if(cursor.x-w >= 0){ - r.min.x = cursor.x-w; - r.max.x = cursor.x; - r.min.y = cursor.y; - r.max.y = cursor.y+defont0.height; + if(curpos.x-w >= 0){ + r.min.x = curpos.x-w; + r.max.x = curpos.x; + r.min.y = curpos.y; + r.max.y = curpos.y+defont0.height; bitblt(&gscreen, r.min, &gscreen, r, Zero); - cursor.x -= w; + curpos.x -= w; } break; default: - if(cursor.x >= window.max.x-w) + if(curpos.x >= window.max.x-w) screenputc("\n"); - cursor = subfstring(&gscreen, cursor, &defont0, buf, S); + curpos = subfstring(&gscreen, curpos, &defont0, buf, S); } } @@ -408,7 +407,7 @@ rep(ulong v, int n) } void -hwcursset(ulong *s, ulong *c, int offx, int offy) +setcursor(ulong *s, ulong *c, int offx, int offy) { Dac *d; int x, y; @@ -453,20 +452,29 @@ hwcursset(ulong *s, ulong *c, int offx, int offy) } void -hwcursmove(int x, int y) +cursoron(int dolock) { Dac *d; + Point p; + + p = mousexy(); d = DAC; - x += 380; /* adjusted by experiment */ - y += 11; /* adjusted by experiment */ + if(dolock) + lock(&cursor); + + p.x += 380; /* adjusted by experiment */ + p.y += 11; /* adjusted by experiment */ d->cr1 = 03; d->cr0 = 01; - d->cr2 = x&0xFF; - d->cr2 = (x>>8)&0xF; - d->cr2 = y&0xFF; - d->cr2 = (y>>8)&0xF; + d->cr2 = p.x&0xFF; + d->cr2 = (p.x>>8)&0xF; + d->cr2 = p.y&0xFF; + d->cr2 = (p.y>>8)&0xF; + + if(dolock) + unlock(&cursor); } int diff --git a/carrera/screen.h b/carrera/screen.h index cc88c2916a18de3811f1d1de960852df7f781251..5f189e08c7930ecb0ac6744a33fe27e7dc6df71b 100644 --- a/carrera/screen.h +++ b/carrera/screen.h @@ -1,8 +1,16 @@ -extern void mouseupdate(int); +typedef struct Cursorinfo Cursorinfo; -#define hwscreenwrite(a, b) +struct Cursorinfo +{ + Cursor; + Lock; +}; -#define mbbpt(x) -#define mbbrect(x) -#define mousescreenupdate() -#define mousectl(s) +extern Cursorinfo cursor; + +extern void mouseupdate(int); +extern void cursoron(int); +#define cursoroff(x) +#define mousectl(s) +extern Point mousexy(void); +#define hwscreenwrite(a, b) diff --git a/pc/devvga.c b/pc/devvga.c index 98fb23f7b6ec194bc84eff5a9133eb9477d68b02..ce22cbaec74607c68f8ddd9baec55d8e5058a757 100644 --- a/pc/devvga.c +++ b/pc/devvga.c @@ -7,6 +7,7 @@ #include "../port/error.h" #include +#include "screen.h" enum { @@ -209,6 +210,7 @@ void vgareset(void) { vgacard = &vgachips[Generic]; + cursor.disable++; } void @@ -219,6 +221,7 @@ vgainit(void) Chan* vgaattach(char *upec) { + print("visible %d disable %d frozen %d\n", cursor.visible, cursor.disable, cursor.frozen); return devattach('v', upec); } @@ -456,6 +459,8 @@ setscreen(int maxx, int maxy, int ldepth) error(Ebadarg); } + lock(&screenlock); + /* * setup a bitmap for the new size */ @@ -497,13 +502,18 @@ setscreen(int maxx, int maxy, int ldepth) window.min = Pt(50, 50); window.max = add(window.min, Pt(10+w*64, Footprint/(BY2WD*gscreen.width))); + if(window.max.y >= gscreen.r.max.y) + window.max.y = gscreen.r.max.y; + if(window.max.x >= gscreen.r.max.x) + window.max.x = gscreen.r.max.x; vgacard->setpage(0); bitblt(&gscreen, window.min, &gscreen, window, Zero); window = inset(window, 5); curpos = window.min; window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; - hwcurs = 0; + + cursorinit(); } /* @@ -1164,3 +1174,166 @@ setcolor(ulong p, ulong r, ulong g, ulong b) unlock(&screenlock); return ~0; } + + +/* + * software cursor + */ + +ulong backbits[16*5]; +ulong workbits[16*5]; +Bitmap cursorwork = +{ + {0, 0, 16+8, 16}, + {0, 0, 16+8, 16}, + 0, + workbits, + 0, + 1, +}; + +Bitmap clr = +{ + {0, 0, 16, 16}, + {0, 0, 16, 16}, + 0, + 0, + 0, + 1, +}; + +Bitmap set = +{ + {0, 0, 16, 16}, + {0, 0, 16, 16}, + 0, + 0, + 0, + 1, +}; + +void +cursorinit(void) +{ + static int already; + + lock(&cursor); + + cursorwork.ldepth = gscreen.ldepth; + cursorwork.width = ((cursorwork.r.max.x << gscreen.ldepth) + 31) >> 5; + cursor.l = cursorwork.width*BY2WD; + + if(!already){ + cursor.disable--; + already = 1; + } + + unlock(&cursor); +} + +void +setcursor(ulong *setbits, ulong *clrbits, int offx, int offy) +{ + USED(offx, offy); + set.base = setbits; + clr.base = clrbits; +} + +void +cursoron(int dolock) +{ + int off; + Rectangle r; + uchar *a; + struct { + Bitmap *dm; + Point p; + Bitmap *sm; + Rectangle r; + Fcode f; + } xx; + extern int graphicssubtile(uchar*, int, int, Rectangle, Rectangle, uchar**); + + if(cursor.disable) + return; + if(dolock) + lock(&cursor); + + if(cursor.visible++ == 0){ + cursor.r.min = mousexy(); + cursor.r.max = add(cursor.r.min, Pt(16, 16)); + cursor.r = raddp(cursor.r, cursor.offset); + + /* bit offset into backup area */ + if(cursor.r.min.x < 0) + off = cursor.r.min.x; + else + off = ((1< 0){ + /* get tile */ + screenunload(xx.r, (uchar*)workbits, cursor.tl, cursor.l, 0); + + /* save for cursoroff */ + memmove(backbits, workbits, cursor.l*16); + + /* add mouse into work area */ + r = Rect(0, 0, Dx(xx.r), Dy(xx.r)); + bitblt(&cursorwork, xx.p, &clr, r, S|D); + bitblt(&cursorwork, xx.p, &set, r, D&~S); + + /* put back tile */ + cursor.clipr = xx.r; + screenload(xx.r, (uchar*)workbits, cursor.tl, cursor.l, 0); + } + } + + if(dolock) + unlock(&cursor); +} + +void +cursoroff(int dolock) +{ + if(cursor.disable) + return; + if(dolock) + lock(&cursor); + if(--cursor.visible == 0 && cursor.tl > 0) + screenload(cursor.clipr, (uchar*)backbits, cursor.tl, cursor.l, 0); + if(dolock) + unlock(&cursor); +} + +void +cursorlock(Rectangle r) +{ + lock(&cursor); + if(rectXrect(cursor.r, r)){ + cursoroff(0); + cursor.frozen = 1; + } + cursor.disable++; + unlock(&cursor); +} + +void +cursorunlock(void) +{ + lock(&cursor); + cursor.disable--; + if(cursor.frozen) + cursoron(0); + cursor.frozen = 0; + unlock(&cursor); +} diff --git a/pc/screen.h b/pc/screen.h new file mode 100644 index 0000000000000000000000000000000000000000..be8f0980350bddec67df1796f54c62eabc984549 --- /dev/null +++ b/pc/screen.h @@ -0,0 +1,20 @@ +typedef struct Cursorinfo Cursorinfo; + +struct Cursorinfo +{ + Cursor; + Lock; + int visible; /* on screen */ + int disable; /* from being used */ + int frozen; /* from being used */ + Rectangle r; /* location */ + Rectangle clipr; /* r clipped into screen */ + int l; /* width of cursorwork (in bytes) */ + int tl; /* scan line byte width of mouse at r */ +}; + +Cursorinfo cursor; +extern void cursoron(int); +extern void cursoroff(int); +extern Point mousexy(void); +extern void cursorinit(void); diff --git a/port/devmouse.c b/port/devmouse.c index 4e0b2bcb0f81aa27483f86b754ae4b6c8dd768b2..e2a272f57f5f6dbed7b289304c713e0dfb1bb889 100644 --- a/port/devmouse.c +++ b/port/devmouse.c @@ -9,26 +9,7 @@ #include "devtab.h" #include "screen.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 { @@ -48,29 +29,12 @@ struct Mouseinfo int open; }; -struct Cursorinfo -{ - Cursor; - Lock; - int visible; /* on screen */ - int disable; /* from being used */ - int frozen; /* from being used */ - Rectangle r; /* location */ - - int l; - int tl; - int setop; - int clrop; - Rectangle clipr; -}; - Mouseinfo mouse; Cursorinfo cursor; int mouseshifted; int mousetype; int mouseswap; -int hwcurs; -Cursor curs; +Cursor curs; Cursor arrow = { @@ -88,45 +52,11 @@ Cursor arrow = }; ulong setbits[16]; -Bitmap set = -{ - {0, 0, 16, 16}, - {0, 0, 16, 16}, - 0, - setbits, - 1, - 0, -}; - ulong clrbits[16]; -Bitmap clr = -{ - {0, 0, 16, 16}, - {0, 0, 16, 16}, - 0, - clrbits, - 1, - 0, -}; - -ulong backbits[16*5]; -ulong workbits[16*5]; -Bitmap cursorwork = -{ - {0, 0, 16+8, 16}, - {0, 0, 16+8, 16}, - 0, - workbits, - 1, - 0, -}; void Cursortocursor(Cursor*); int mousechanged(void*); -extern void screenload(Rectangle, uchar*, int, int, int); -extern void screenunload(Rectangle, uchar*, int, int, int); - enum{ Qdir, Qcursor, @@ -147,49 +77,19 @@ extern Bitmap 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? */ curs = arrow; Cursortocursor(&arrow); } -void -cursorinit(void) -{ - cursorwork.ldepth = gscreen.ldepth; - cursorwork.width = ((cursorwork.r.max.x << gscreen.ldepth) + 31) >> 5; - - cursor.l = cursorwork.width*BY2WD; - - if(flipping){ - cursor.setop = flipD[S|D]; - cursor.clrop = flipD[D&~S]; - } else { - cursor.setop = S|D; - cursor.clrop = D&~S; - } -} - void mouseinit(void) { if(!conf.monitor) return; - if(gscreen.ldepth > 3){ - print("mouse can't work ldepth > 3"); - cursor.disable = 1; - } - - cursorinit(); - cursoron(1); } @@ -198,7 +98,6 @@ mouseattach(char *spec) { if(!conf.monitor) error(Egreg); - cursorinit(); return devattach('m', spec); } @@ -408,7 +307,7 @@ Cursortocursor(Cursor *c) uchar *p; lock(&cursor); - memmove(&cursor, c, sizeof(Cursor)); + memmove(&cursor.Cursor, c, sizeof(Cursor)); for(i=0; i<16; i++){ p = (uchar*)&setbits[i]; *p = c->set[2*i]; @@ -417,115 +316,10 @@ Cursortocursor(Cursor *c) *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 -cursorlock(Rectangle r) -{ - if(hwcurs) - return; - lock(&cursor); - if(rectXrect(cursor.r, r)){ - cursoroff(0); - cursor.frozen = 1; - } - cursor.disable++; + setcursor(setbits, clrbits, cursor.offset.x, cursor.offset.y); unlock(&cursor); } -void -cursorunlock(void) -{ - if(hwcurs) - return; - lock(&cursor); - cursor.disable--; - if(cursor.frozen) - cursoron(0); - cursor.frozen = 0; - unlock(&cursor); -} - -typedef struct -{ - Bitmap *dm; - Point p; - Bitmap *sm; - Rectangle r; - Fcode f; -} XXX; - -void -cursoron(int dolock) -{ - int off; - Rectangle r; - uchar *a; - XXX x; - extern int graphicssubtile(uchar*, int, int, Rectangle, Rectangle, uchar**); - - 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); - - /* bit offset into backup area */ - off = ((1< 0){ - /* get tile */ - screenunload(x.r, (uchar*)workbits, cursor.tl, cursor.l, 0); - - /* save for cursoroff */ - memmove(backbits, workbits, cursor.l*16); - - /* add mouse into work area */ - r = Rect(0, 0, Dx(x.r), Dy(x.r)); - bitblt(&cursorwork, x.p, &clr, r, cursor.clrop); - bitblt(&cursorwork, x.p, &set, r, cursor.setop); - - /* put back tile */ - cursor.clipr = x.r; - screenload(x.r, (uchar*)workbits, cursor.tl, cursor.l, 0); - } - } - } - if(dolock) - unlock(&cursor); -} - -void -cursoroff(int dolock) -{ - if(cursor.disable) - return; - if(dolock) - lock(&cursor); - if(--cursor.visible == 0 && !hwcurs && cursor.tl > 0) - screenload(cursor.clipr, (uchar*)backbits, cursor.tl, cursor.l, 0); - if(dolock) - unlock(&cursor); -} /* * called by the clock routine to redraw the cursor @@ -652,3 +446,9 @@ mousechanged(void *m) USED(m); return mouse.lastcounter - mouse.counter; } + +Point +mousexy(void) +{ + return mouse.xy; +} diff --git a/port/portfns.h b/port/portfns.h index 3827d8b39c446fd8243ac78d91d7a12ef0b33739..54ceea9400782baee50ce2c179bdd37c84778279 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -43,8 +43,6 @@ void copen(Chan*); void copypage(Page*, Page*); int cread(Chan*, uchar*, int, ulong); void cupdate(Chan*, uchar*, int, ulong); -void cursoroff(int); -void cursoron(int); void cwrite(Chan*, uchar*, int, ulong); int decref(Ref*); int decrypt(void*, void*, int); @@ -93,8 +91,6 @@ void gotolabel(Label*); int haswaitq(void*); long hostdomainwrite(char*, int); long hostownerwrite(char*, int); -void hwcursmove(int, int); -void hwcursset(ulong*, ulong*, int, int); void iallocinit(void); long ibrk(ulong, int); void ilock(Lock*); @@ -232,6 +228,7 @@ long seconds(void); ulong segattach(Proc*, ulong, char *, ulong, ulong); void segpage(Segment*, Page*); int setcolor(ulong, ulong, ulong, ulong); +void setcursor(ulong*, ulong*, int, int); void setkernur(Ureg*, Proc*); int setlabel(Label*); void setregisters(Ureg*, char*, char*, int);