M carrera/screen.c => carrera/screen.c +34 -26
@@ 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
M carrera/screen.h => carrera/screen.h +14 -6
@@ 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)
M pc/devvga.c => pc/devvga.c +174 -1
@@ 7,6 7,7 @@
#include "../port/error.h"
#include <libg.h>
+#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<<gscreen.ldepth)*cursor.r.min.x) & 7;
+
+ /* clip the cursor rectangle */
+ xx.dm = &cursorwork;
+ xx.p = Pt(off, 0);
+ xx.sm = &gscreen;
+ xx.r = cursor.r;
+ bitbltclip(&xx);
+
+ /* tile width */
+ cursor.tl = graphicssubtile(0, cursor.l, gscreen.ldepth,
+ gscreen.r, xx.r, &a);
+ if(cursor.tl > 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);
+}
A pc/screen.h => pc/screen.h +20 -0
@@ 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);
M port/devmouse.c => port/devmouse.c +9 -209
@@ 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<<gscreen.ldepth)*cursor.r.min.x) & 7;
-
- /* clip the cursor rectangle */
- x.dm = &cursorwork;
- x.p = Pt(off, 0);
- x.sm = &gscreen;
- x.r = cursor.r;
- bitbltclip(&x);
-
- /* tile width */
- cursor.tl = graphicssubtile(0, cursor.l, gscreen.ldepth,
- gscreen.r, x.r, &a);
- if(cursor.tl > 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;
+}
M port/portfns.h => port/portfns.h +1 -4
@@ 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);