summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/9/bcm/fns.h1
-rw-r--r--sys/src/9/bcm/main.c2
-rw-r--r--sys/src/9/bcm/picpuf2
-rw-r--r--sys/src/9/bcm/pif2
-rw-r--r--sys/src/9/bcm/screen.c200
-rw-r--r--sys/src/9/bcm/screen.h12
-rw-r--r--sys/src/9/omap/beagle2
-rw-r--r--sys/src/9/omap/screen.c167
-rw-r--r--sys/src/9/omap/screen.h13
-rw-r--r--sys/src/9/pc/devvga.c6
-rw-r--r--sys/src/9/pc/pccpuf2
-rw-r--r--sys/src/9/pc/pcf2
-rw-r--r--sys/src/9/pc/screen.c260
-rw-r--r--sys/src/9/pc/screen.h12
-rw-r--r--sys/src/9/port/devmouse.c90
-rw-r--r--sys/src/9/port/portmkfile1
-rw-r--r--sys/src/9/port/swcursor.c133
17 files changed, 298 insertions, 609 deletions
diff --git a/sys/src/9/bcm/fns.h b/sys/src/9/bcm/fns.h
index 92615d9ed..1c480cc14 100644
--- a/sys/src/9/bcm/fns.h
+++ b/sys/src/9/bcm/fns.h
@@ -64,7 +64,6 @@ extern void setpower(int, int);
extern void setr13(int, u32int*);
extern int splfhi(void);
extern int splflo(void);
-extern void swcursorinit(void);
extern int tas(void *);
extern void touser(uintptr);
extern void trapinit(void);
diff --git a/sys/src/9/bcm/main.c b/sys/src/9/bcm/main.c
index 4a00d1b13..1b78c80d1 100644
--- a/sys/src/9/bcm/main.c
+++ b/sys/src/9/bcm/main.c
@@ -249,8 +249,6 @@ main(void)
clockinit();
printinit();
timersinit();
- if(conf.monitor)
- swcursorinit();
cpuidprint();
archreset();
diff --git a/sys/src/9/bcm/picpuf b/sys/src/9/bcm/picpuf
index 7ec5d9881..fcdc080dd 100644
--- a/sys/src/9/bcm/picpuf
+++ b/sys/src/9/bcm/picpuf
@@ -14,7 +14,7 @@ dev
cap
fs
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum inferno
- draw screen
+ draw screen swcursor
mouse mouse
uart
diff --git a/sys/src/9/bcm/pif b/sys/src/9/bcm/pif
index cf3c66485..f209a1211 100644
--- a/sys/src/9/bcm/pif
+++ b/sys/src/9/bcm/pif
@@ -14,7 +14,7 @@ dev
cap
fs
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum inferno
- draw screen
+ draw screen swcursor
mouse mouse
uart
diff --git a/sys/src/9/bcm/screen.c b/sys/src/9/bcm/screen.c
index e96fa4fdf..fe7ed6c93 100644
--- a/sys/src/9/bcm/screen.c
+++ b/sys/src/9/bcm/screen.c
@@ -69,203 +69,32 @@ static void myscreenputs(char *s, int n);
static void screenputc(char *buf);
static void screenwin(void);
-/*
- * Software cursor.
- */
-static int swvisible; /* is the cursor visible? */
-static int swenabled; /* is the cursor supposed to be on the screen? */
-static Memimage *swback; /* screen under cursor */
-static Memimage *swimg; /* cursor image */
-static Memimage *swmask; /* cursor mask */
-static Memimage *swimg1;
-static Memimage *swmask1;
-
-static Point swoffset;
-static Rectangle swrect; /* screen rectangle in swback */
-static Point swpt; /* desired cursor location */
-static Point swvispt; /* actual cursor location */
-static int swvers; /* incremented each time cursor image changes */
-static int swvisvers; /* the version on the screen */
-
-/*
- * called with drawlock locked for us, most of the time.
- * kernel prints at inopportune times might mean we don't
- * hold the lock, but memimagedraw is now reentrant so
- * that should be okay: worst case we get cursor droppings.
- */
-static void
-swcursorhide(void)
-{
- if(swvisible == 0)
- return;
- if(swback == nil)
- return;
- swvisible = 0;
- memimagedraw(gscreen, swrect, swback, ZP, memopaque, ZP, S);
- flushmemscreen(swrect);
-}
-
-static void
-swcursoravoid(Rectangle r)
-{
- if(swvisible && rectXrect(r, swrect))
- swcursorhide();
-}
-
-static void
-swcursordraw(void)
-{
- int dounlock;
-
- if(swvisible)
- return;
- if(swenabled == 0)
- return;
- if(swback == nil || swimg1 == nil || swmask1 == nil)
- return;
- dounlock = canqlock(&drawlock);
- swvispt = swpt;
- swvisvers = swvers;
- swrect = rectaddpt(Rect(0,0,16,16), swvispt);
- memimagedraw(swback, swback->r, gscreen, swpt, memopaque, ZP, S);
- memimagedraw(gscreen, swrect, swimg1, ZP, swmask1, ZP, SoverD);
- flushmemscreen(swrect);
- swvisible = 1;
- if(dounlock)
- qunlock(&drawlock);
-}
-
-int
-cursoron(int dolock)
-{
- int retry;
-
- if (dolock)
- lock(&cursor);
- if (canqlock(&drawlock)) {
- retry = 0;
- swcursorhide();
- swcursordraw();
- qunlock(&drawlock);
- } else
- retry = 1;
- if (dolock)
- unlock(&cursor);
- return retry;
-}
-
void
-cursoroff(int dolock)
+cursoron(void)
{
- if (dolock)
- lock(&cursor);
+ qlock(&drawlock);
+ lock(&cursor);
swcursorhide();
- if (dolock)
- unlock(&cursor);
+ swcursordraw(mousexy());
+ unlock(&cursor);
+ qunlock(&drawlock);
}
-static void
-swload(Cursor *curs)
+void
+cursoroff(void)
{
- uchar *ip, *mp;
- int i, j, set, clr;
-
- if(!swimg || !swmask || !swimg1 || !swmask1)
- return;
- /*
- * Build cursor image and mask.
- * Image is just the usual cursor image
- * but mask is a transparent alpha mask.
- *
- * The 16x16x8 memimages do not have
- * padding at the end of their scan lines.
- */
- ip = byteaddr(swimg, ZP);
- mp = byteaddr(swmask, ZP);
- for(i=0; i<32; i++){
- set = curs->set[i];
- clr = curs->clr[i];
- for(j=0x80; j; j>>=1){
- *ip++ = set&j ? 0x00 : 0xFF;
- *mp++ = (clr|set)&j ? 0xFF : 0x00;
- }
- }
- swoffset = curs->offset;
- swvers++;
- memimagedraw(swimg1, swimg1->r, swimg, ZP, memopaque, ZP, S);
- memimagedraw(swmask1, swmask1->r, swmask, ZP, memopaque, ZP, S);
+ qlock(&drawlock);
+ lock(&cursor);
+ swcursorhide();
+ unlock(&cursor);
+ qunlock(&drawlock);
}
/* called from devmouse */
void
setcursor(Cursor* curs)
{
- cursoroff(0);
- swload(curs);
- cursoron(0);
-}
-
-static int
-swmove(Point p)
-{
- swpt = addpt(p, swoffset);
- return 0;
-}
-
-static void
-swcursorclock(void)
-{
- int x;
-
- if(!swenabled)
- return;
- swmove(mousexy());
- if(swvisible && eqpt(swpt, swvispt) && swvers==swvisvers)
- return;
-
- x = splhi();
- if(swenabled)
- if(!swvisible || !eqpt(swpt, swvispt) || swvers!=swvisvers)
- if(canqlock(&drawlock)){
- swcursorhide();
- swcursordraw();
- qunlock(&drawlock);
- }
- splx(x);
-}
-
-void
-swcursorinit(void)
-{
- static int init;
-
- if(!init){
- init = 1;
- addclock0link(swcursorclock, 10);
- swenabled = 1;
- }
- if(swback){
- freememimage(swback);
- freememimage(swmask);
- freememimage(swmask1);
- freememimage(swimg);
- freememimage(swimg1);
- }
-
- swback = allocmemimage(Rect(0,0,32,32), gscreen->chan);
- swmask = allocmemimage(Rect(0,0,16,16), GREY8);
- swmask1 = allocmemimage(Rect(0,0,16,16), GREY1);
- swimg = allocmemimage(Rect(0,0,16,16), GREY8);
- swimg1 = allocmemimage(Rect(0,0,16,16), GREY1);
- if(swback==nil || swmask==nil || swmask1==nil || swimg==nil || swimg1 == nil){
- print("software cursor: allocmemimage fails\n");
- return;
- }
-
- memfillcolor(swmask, DOpaque);
- memfillcolor(swmask1, DOpaque);
- memfillcolor(swimg, DBlack);
- memfillcolor(swimg1, DBlack);
+ swcursorload(curs);
}
int
@@ -348,6 +177,7 @@ screeninit(void)
memdefont = getmemdefont();
screenwin();
screenputs = myscreenputs;
+ swcursorinit();
}
void
diff --git a/sys/src/9/bcm/screen.h b/sys/src/9/bcm/screen.h
index 8703796a9..9c45e3a2f 100644
--- a/sys/src/9/bcm/screen.h
+++ b/sys/src/9/bcm/screen.h
@@ -21,16 +21,24 @@ extern Cursor arrow;
/* mouse.c */
extern void mousectl(Cmdbuf*);
extern void mouseresize(void);
+extern void mouseredraw(void);
/* screen.c */
extern void blankscreen(int);
extern void flushmemscreen(Rectangle);
extern uchar* attachscreen(Rectangle*, ulong*, int*, int*, int*);
-extern int cursoron(int);
-extern void cursoroff(int);
+extern void cursoron(void);
+extern void cursoroff(void);
extern void setcursor(Cursor*);
/* devdraw.c */
extern QLock drawlock;
#define ishwimage(i) 1 /* for ../port/devdraw.c */
+
+/* swcursor.c */
+void swcursorhide(void);
+void swcursoravoid(Rectangle);
+void swcursordraw(Point);
+void swcursorload(Cursor *);
+void swcursorinit(void);
diff --git a/sys/src/9/omap/beagle b/sys/src/9/omap/beagle
index 8852bd7d4..3dea87477 100644
--- a/sys/src/9/omap/beagle
+++ b/sys/src/9/omap/beagle
@@ -24,7 +24,7 @@ dev
ether netif
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum inferno
- draw screen
+ draw screen swcursor
dss
mouse
diff --git a/sys/src/9/omap/screen.c b/sys/src/9/omap/screen.c
index e47fd2821..f2ec47054 100644
--- a/sys/src/9/omap/screen.c
+++ b/sys/src/9/omap/screen.c
@@ -346,174 +346,33 @@ screenpower(int on)
blankscreen(on == 0);
}
-/*
- * called with drawlock locked for us, most of the time.
- * kernel prints at inopportune times might mean we don't
- * hold the lock, but memimagedraw is now reentrant so
- * that should be okay: worst case we get cursor droppings.
- */
-void
-swcursorhide(void)
-{
- if(swvisible == 0)
- return;
- if(swback == nil)
- return;
- swvisible = 0;
- memimagedraw(gscreen, swrect, swback, ZP, memopaque, ZP, S);
- flushmemscreen(swrect);
-}
-
-void
-swcursoravoid(Rectangle r)
-{
- if(swvisible && rectXrect(r, swrect))
- swcursorhide();
-}
-
-void
-swcursordraw(void)
-{
- if(swvisible)
- return;
- if(swenabled == 0)
- return;
- if(swback == nil || swimg1 == nil || swmask1 == nil)
- return;
-// assert(!canqlock(&drawlock)); // assertion fails on omap
- swvispt = swpt;
- swvisvers = swvers;
- swrect = rectaddpt(Rect(0,0,16,16), swvispt);
- memimagedraw(swback, swback->r, gscreen, swpt, memopaque, ZP, S);
- memimagedraw(gscreen, swrect, swimg1, ZP, swmask1, ZP, SoverD);
- flushmemscreen(swrect);
- swvisible = 1;
-}
-
-int
-cursoron(int dolock)
-{
- if (dolock)
- lock(&oscreen);
- cursoroff(0);
- swcursordraw();
- if (dolock)
- unlock(&oscreen);
- return 0;
-}
-
void
-cursoroff(int dolock)
+cursoron(void)
{
- if (dolock)
- lock(&oscreen);
+ qlock(&drawlock);
+ lock(&cursor);
swcursorhide();
- if (dolock)
- unlock(&oscreen);
+ swcursordraw(mousexy());
+ unlock(&cursor);
+ qunlock(&drawlock);
}
void
-swload(Cursor *curs)
+cursoroff(void)
{
- uchar *ip, *mp;
- int i, j, set, clr;
-
- if(!swimg || !swmask || !swimg1 || !swmask1)
- return;
- /*
- * Build cursor image and mask.
- * Image is just the usual cursor image
- * but mask is a transparent alpha mask.
- *
- * The 16x16x8 memimages do not have
- * padding at the end of their scan lines.
- */
- ip = byteaddr(swimg, ZP);
- mp = byteaddr(swmask, ZP);
- for(i=0; i<32; i++){
- set = curs->set[i];
- clr = curs->clr[i];
- for(j=0x80; j; j>>=1){
- *ip++ = set&j ? 0x00 : 0xFF;
- *mp++ = (clr|set)&j ? 0xFF : 0x00;
- }
- }
- swoffset = curs->offset;
- swvers++;
- memimagedraw(swimg1, swimg1->r, swimg, ZP, memopaque, ZP, S);
- memimagedraw(swmask1, swmask1->r, swmask, ZP, memopaque, ZP, S);
+ qlock(&drawlock);
+ lock(&cursor);
+ swcursorhide();
+ unlock(&cursor);
+ qunlock(&drawlock);
}
/* called from devmouse */
void
setcursor(Cursor* curs)
{
- cursoroff(1);
oscreen.Cursor = *curs;
- swload(curs);
- cursoron(1);
-}
-
-int
-swmove(Point p)
-{
- swpt = addpt(p, swoffset);
- return 0;
-}
-
-void
-swcursorclock(void)
-{
- int x;
-
- if(!swenabled)
- return;
- swmove(mousexy());
- if(swvisible && eqpt(swpt, swvispt) && swvers==swvisvers)
- return;
-
- x = splhi();
- if(swenabled)
- if(!swvisible || !eqpt(swpt, swvispt) || swvers!=swvisvers)
- if(canqlock(&drawlock)){
- swcursorhide();
- swcursordraw();
- qunlock(&drawlock);
- }
- splx(x);
-}
-
-void
-swcursorinit(void)
-{
- static int init;
-
- if(!init){
- init = 1;
- addclock0link(swcursorclock, 10);
- }
- if(swback){
- freememimage(swback);
- freememimage(swmask);
- freememimage(swmask1);
- freememimage(swimg);
- freememimage(swimg1);
- }
-
- swback = allocmemimage(Rect(0,0,32,32), gscreen->chan);
- swmask = allocmemimage(Rect(0,0,16,16), GREY8);
- swmask1 = allocmemimage(Rect(0,0,16,16), GREY1);
- swimg = allocmemimage(Rect(0,0,16,16), GREY8);
- swimg1 = allocmemimage(Rect(0,0,16,16), GREY1);
- if(swback==nil || swmask==nil || swmask1==nil || swimg==nil || swimg1 == nil){
- print("software cursor: allocmemimage fails\n");
- return;
- }
-
- memfillcolor(swmask, DOpaque);
- memfillcolor(swmask1, DOpaque);
- memfillcolor(swimg, DBlack);
- memfillcolor(swimg1, DBlack);
+ swcursorload(curs);
}
/* called from main and possibly later from devdss to change resolution */
diff --git a/sys/src/9/omap/screen.h b/sys/src/9/omap/screen.h
index 6eff3649c..6083aea15 100644
--- a/sys/src/9/omap/screen.h
+++ b/sys/src/9/omap/screen.h
@@ -20,12 +20,13 @@ extern Point mousexy(void);
extern void mouseaccelerate(int);
extern void mouseresize(void);
+extern void mouseredraw(void);
/* screen.c */
extern uchar* attachscreen(Rectangle*, ulong*, int*, int*, int*);
extern void flushmemscreen(Rectangle);
-extern int cursoron(int);
-extern void cursoroff(int);
+extern void cursoron(void);
+extern void cursoroff(void);
extern void setcursor(Cursor*);
extern int screensize(int, int, int, ulong);
extern int screenaperture(int, int);
@@ -49,6 +50,13 @@ extern QLock drawlock;
#define ishwimage(i) 0 /* for ../port/devdraw.c */
+/* swcursor.c */
+void swcursorhide(void);
+void swcursoravoid(Rectangle);
+void swcursordraw(Point);
+void swcursorload(Cursor *);
+void swcursorinit(void);
+
/* for communication between devdss.c and screen.c */
enum {
@@ -93,7 +101,6 @@ struct Settings {
};
struct OScreen {
- Lock;
Cursor;
Settings *settings;
int open;
diff --git a/sys/src/9/pc/devvga.c b/sys/src/9/pc/devvga.c
index 14df25b89..3867d36dc 100644
--- a/sys/src/9/pc/devvga.c
+++ b/sys/src/9/pc/devvga.c
@@ -349,7 +349,7 @@ vgactl(Cmdbuf *cb)
if(chantodepth(chan) != z)
error("depth, channel do not match");
- cursoroff(1);
+ cursoroff();
deletescreenimage();
if(screensize(x, y, z, chan))
error(Egreg);
@@ -397,7 +397,7 @@ vgactl(Cmdbuf *cb)
y = scr->gscreen->r.max.y;
z = scr->gscreen->depth;
chan = scr->gscreen->chan;
- cursoroff(1);
+ cursoroff();
deletescreenimage();
if(screensize(x, y, z, chan))
error(Egreg);
@@ -411,7 +411,7 @@ vgactl(Cmdbuf *cb)
hwaccel = !scr->softscreen && (scr->scroll || scr->fill);
vgascreenwin(scr);
resetscreenimage();
- cursoron(1);
+ cursoron();
return;
case CMlinear:
diff --git a/sys/src/9/pc/pccpuf b/sys/src/9/pc/pccpuf
index b34e46c2d..9a808bf81 100644
--- a/sys/src/9/pc/pccpuf
+++ b/sys/src/9/pc/pccpuf
@@ -23,7 +23,7 @@ dev
ether netif
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum386 inferno
- draw screen vga vgax
+ draw screen vga vgax swcursor
mouse mouse
kbd
vga
diff --git a/sys/src/9/pc/pcf b/sys/src/9/pc/pcf
index 308faf7b9..6bb744d53 100644
--- a/sys/src/9/pc/pcf
+++ b/sys/src/9/pc/pcf
@@ -21,7 +21,7 @@ dev
ether netif
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum386 inferno
- draw screen vga vgax
+ draw screen vga vgax swcursor
mouse mouse
kbd
vga
diff --git a/sys/src/9/pc/screen.c b/sys/src/9/pc/screen.c
index f7426b783..42e31e65a 100644
--- a/sys/src/9/pc/screen.c
+++ b/sys/src/9/pc/screen.c
@@ -23,7 +23,7 @@ Memimage *gscreen;
VGAscr vgascreen[1];
-Cursor arrow = {
+Cursor arrow = {
{ -1, -1 },
{ 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C,
0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04,
@@ -37,8 +37,6 @@ Cursor arrow = {
},
};
-int didswcursorinit;
-
int
screensize(int x, int y, int, ulong chan)
{
@@ -101,8 +99,7 @@ screensize(int x, int y, int, ulong chan)
poperror();
drawcmap();
- if(didswcursorinit)
- swcursorinit();
+ swcursorinit();
qunlock(&drawlock);
poperror();
@@ -327,27 +324,63 @@ setcolor(ulong p, ulong r, ulong g, ulong b)
return setpalette(p, r, g, b);
}
+void
+swenable(VGAscr*)
+{
+ swcursorload(&arrow);
+}
+
+void
+swdisable(VGAscr*)
+{
+}
+
+void
+swload(VGAscr*, Cursor *curs)
+{
+ swcursorload(curs);
+}
+
int
-cursoron(int dolock)
+swmove(VGAscr*, Point p)
+{
+ swcursorhide();
+ swcursordraw(p);
+ return 0;
+}
+
+VGAcur swcursor =
+{
+ "soft",
+ swenable,
+ swdisable,
+ swload,
+ swmove,
+};
+
+
+void
+cursoron(void)
{
VGAscr *scr;
- int v;
+ VGAcur *cur;
scr = &vgascreen[0];
- if(scr->cur == nil || scr->cur->move == nil)
- return 0;
-
- if(dolock)
- lock(&cursor);
- v = scr->cur->move(scr, mousexy());
- if(dolock)
- unlock(&cursor);
+ cur = scr->cur;
+ if(cur == nil || cur->move == nil)
+ return;
- return v;
+ if(cur == &swcursor)
+ qlock(&drawlock);
+ lock(&cursor);
+ cur->move(scr, mousexy());
+ unlock(&cursor);
+ if(cur == &swcursor)
+ qunlock(&drawlock);
}
void
-cursoroff(int)
+cursoroff(void)
{
}
@@ -532,196 +565,3 @@ vgalinearaddr(VGAscr *scr, ulong paddr, int size)
poperror();
}
}
-
-
-/*
- * Software cursor.
- */
-int swvisible; /* is the cursor visible? */
-int swenabled; /* is the cursor supposed to be on the screen? */
-Memimage* swback; /* screen under cursor */
-Memimage* swimg; /* cursor image */
-Memimage* swmask; /* cursor mask */
-Memimage* swimg1;
-Memimage* swmask1;
-
-Point swoffset;
-Rectangle swrect; /* screen rectangle in swback */
-Point swpt; /* desired cursor location */
-Point swvispt; /* actual cursor location */
-int swvers; /* incremented each time cursor image changes */
-int swvisvers; /* the version on the screen */
-
-/*
- * called with drawlock locked for us, most of the time.
- * kernel prints at inopportune times might mean we don't
- * hold the lock, but memimagedraw is now reentrant so
- * that should be okay: worst case we get cursor droppings.
- */
-void
-swcursorhide(void)
-{
- if(swvisible == 0)
- return;
- if(swback == nil)
- return;
- swvisible = 0;
- memimagedraw(gscreen, swrect, swback, ZP, memopaque, ZP, S);
- flushmemscreen(swrect);
-}
-
-void
-swcursoravoid(Rectangle r)
-{
- if(swvisible && rectXrect(r, swrect))
- swcursorhide();
-}
-
-void
-swcursordraw(void)
-{
- if(swvisible)
- return;
- if(swenabled == 0)
- return;
- if(swback == nil || swimg1 == nil || swmask1 == nil)
- return;
- assert(!canqlock(&drawlock));
- swvispt = swpt;
- swvisvers = swvers;
- swrect = rectaddpt(Rect(0,0,16,16), swvispt);
- memimagedraw(swback, swback->r, gscreen, swpt, memopaque, ZP, S);
- memimagedraw(gscreen, swrect, swimg1, ZP, swmask1, ZP, SoverD);
- flushmemscreen(swrect);
- swvisible = 1;
-}
-
-void
-swload(VGAscr*, Cursor *curs)
-{
- uchar *ip, *mp;
- int i, j, set, clr;
-
- if(!swimg || !swmask || !swimg1 || !swmask1)
- return;
- /*
- * Build cursor image and mask.
- * Image is just the usual cursor image
- * but mask is a transparent alpha mask.
- *
- * The 16x16x8 memimages do not have
- * padding at the end of their scan lines.
- */
- ip = byteaddr(swimg, ZP);
- mp = byteaddr(swmask, ZP);
- for(i=0; i<32; i++){
- set = curs->set[i];
- clr = curs->clr[i];
- for(j=0x80; j; j>>=1){
- *ip++ = set&j ? 0x00 : 0xFF;
- *mp++ = (clr|set)&j ? 0xFF : 0x00;
- }
- }
- swoffset = curs->offset;
- swvers++;
- memimagedraw(swimg1, swimg1->r, swimg, ZP, memopaque, ZP, S);
- memimagedraw(swmask1, swmask1->r, swmask, ZP, memopaque, ZP, S);
-}
-
-int
-swmove(VGAscr*, Point p)
-{
- swpt = addpt(p, swoffset);
- return 0;
-}
-
-void
-swcursorclock(void)
-{
- int x;
-
- if(!swenabled)
- return;
- if(swvisible && eqpt(swpt, swvispt) && swvers==swvisvers)
- return;
-
- x = splhi();
- if(swenabled)
- if(!swvisible || !eqpt(swpt, swvispt) || swvers!=swvisvers)
- if(canqlock(&drawlock)){
- swcursorhide();
- swcursordraw();
- qunlock(&drawlock);
- }
- splx(x);
-}
-
-void
-swcursorinit(void)
-{
- static int init;
- VGAscr *scr;
-
- didswcursorinit = 1;
- if(!init){
- init = 1;
- addclock0link(swcursorclock, 10);
- }
-
- scr = &vgascreen[0];
- if(scr->gscreen==nil)
- return;
-
- if(swback){
- freememimage(swback);
- freememimage(swmask);
- freememimage(swmask1);
- freememimage(swimg);
- freememimage(swimg1);
- }
- swback = allocmemimage(Rect(0,0,32,32), gscreen->chan);
- swmask = allocmemimage(Rect(0,0,16,16), GREY8);
- swmask1 = allocmemimage(Rect(0,0,16,16), GREY1);
- swimg = allocmemimage(Rect(0,0,16,16), GREY8);
- swimg1 = allocmemimage(Rect(0,0,16,16), GREY1);
- if(swback==nil || swmask==nil || swmask1==nil || swimg==nil || swimg1 == nil)
- print("software cursor: allocmemimage fails");
- memfillcolor(swback, DTransparent);
- memfillcolor(swmask, DOpaque);
- memfillcolor(swmask1, DOpaque);
- memfillcolor(swimg, DBlack);
- memfillcolor(swimg1, DBlack);
-}
-
-/*
- * Need to lock drawlock for ourselves.
- */
-void
-swenable(VGAscr *scr)
-{
- swenabled = 1;
- if(canqlock(&drawlock)){
- swload(scr, &arrow);
- swcursordraw();
- qunlock(&drawlock);
- }
-}
-
-void
-swdisable(VGAscr*)
-{
- swenabled = 0;
- if(canqlock(&drawlock)){
- swcursorhide();
- qunlock(&drawlock);
- }
-}
-
-VGAcur swcursor =
-{
- "soft",
- swenable,
- swdisable,
- swload,
- swmove,
-};
diff --git a/sys/src/9/pc/screen.h b/sys/src/9/pc/screen.h
index 9cf40bc05..bbe6b2512 100644
--- a/sys/src/9/pc/screen.h
+++ b/sys/src/9/pc/screen.h
@@ -132,6 +132,7 @@ enum {
/* mouse.c */
extern void mousectl(Cmdbuf*);
extern void mouseresize(void);
+extern void mouseredraw(void);
/* screen.c */
extern int hwaccel; /* use hw acceleration; default on */
@@ -140,8 +141,8 @@ extern int panning; /* use virtual screen panning; default off */
extern void addvgaseg(char*, ulong, ulong);
extern uchar* attachscreen(Rectangle*, ulong*, int*, int*, int*);
extern void flushmemscreen(Rectangle);
-extern int cursoron(int);
-extern void cursoroff(int);
+extern void cursoron(void);
+extern void cursoroff(void);
extern void setcursor(Cursor*);
extern int screensize(int, int, int, ulong);
extern int screenaperture(int, int);
@@ -176,3 +177,10 @@ extern void vgablank(VGAscr*, int);
extern Lock vgascreenlock;
#define ishwimage(i) (vgascreen[0].gscreendata && (i)->data->bdata == vgascreen[0].gscreendata->bdata)
+
+/* swcursor.c */
+void swcursorhide(void);
+void swcursoravoid(Rectangle);
+void swcursordraw(Point);
+void swcursorload(Cursor *);
+void swcursorinit(void);
diff --git a/sys/src/9/port/devmouse.c b/sys/src/9/port/devmouse.c
index 676639f49..73d43d19a 100644
--- a/sys/src/9/port/devmouse.c
+++ b/sys/src/9/port/devmouse.c
@@ -33,16 +33,13 @@ struct Mouseinfo
{
Lock;
Mousestate;
- int dx;
- int dy;
- int track; /* dx & dy updated */
int redraw; /* update cursor on screen */
+ Rendez redrawr; /* wait for cursor screen updates */
ulong lastcounter; /* value when /dev/mouse read */
ulong lastresize;
ulong resize;
Rendez r;
Ref;
- QLock;
int open;
int acceleration;
int maxacc;
@@ -77,8 +74,7 @@ Cursor curs;
void Cursortocursor(Cursor*);
int mousechanged(void*);
-
-static void mouseclock(void);
+void mouseredraw(void);
enum{
Qdir,
@@ -114,8 +110,6 @@ mousereset(void)
curs = arrow;
Cursortocursor(&arrow);
- /* redraw cursor about 30 times per second */
- addclock0link(mouseclock, 33);
}
static int
@@ -129,6 +123,8 @@ mousedevgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp)
return rc;
}
+static void mouseproc(void*);
+
static void
mouseinit(void)
{
@@ -137,8 +133,10 @@ mouseinit(void)
curs = arrow;
Cursortocursor(&arrow);
- cursoron(1);
+ cursoron();
mousetime = seconds();
+
+ kproc("mouse", mouseproc, 0);
}
static Chan*
@@ -222,13 +220,15 @@ mouseclose(Chan *c)
unlock(&mouse);
return;
}
- if(--mouse.ref == 0){
- cursoroff(1);
- curs = arrow;
- Cursortocursor(&arrow);
- cursoron(1);
+ if(--mouse.ref != 0){
+ unlock(&mouse);
+ return;
}
unlock(&mouse);
+ cursoroff();
+ curs = arrow;
+ Cursortocursor(&arrow);
+ cursoron();
}
}
@@ -373,7 +373,7 @@ mousewrite(Chan *c, void *va, long n, vlong)
error(Eisdir);
case Qcursor:
- cursoroff(1);
+ cursoroff();
if(n < 2*4+2*2*16){
curs = arrow;
Cursortocursor(&arrow);
@@ -385,11 +385,7 @@ mousewrite(Chan *c, void *va, long n, vlong)
memmove(curs.set, p+40, 2*16);
Cursortocursor(&curs);
}
- qlock(&mouse);
- mouse.redraw = 1;
- mouseclock();
- qunlock(&mouse);
- cursoron(1);
+ cursoron();
return n;
case Qmousectl:
@@ -466,14 +462,10 @@ mousewrite(Chan *c, void *va, long n, vlong)
if(p == 0)
error(Eshort);
pt.y = strtoul(p, 0, 0);
- qlock(&mouse);
- if(ptinrect(pt, gscreen->r)){
+ if(gscreen != nil && ptinrect(pt, gscreen->r)){
mouse.xy = pt;
- mouse.redraw = 1;
- mouse.track = 1;
- mouseclock();
+ mousetrack(0, 0, mouse.buttons, TK2MS(MACHP(0)->ticks));
}
- qunlock(&mouse);
return n;
}
@@ -505,32 +497,40 @@ Dev mousedevtab = {
void
Cursortocursor(Cursor *c)
{
+ qlock(&drawlock);
lock(&cursor);
memmove(&cursor.Cursor, c, sizeof(Cursor));
setcursor(c);
unlock(&cursor);
+ qunlock(&drawlock);
}
+static int
+shouldredraw(void*)
+{
+ return mouse.redraw != 0;
+}
+
/*
- * called by the clock routine to redraw the cursor
+ * process that redraws the cursor
*/
static void
-mouseclock(void)
+mouseproc(void*)
{
- if(mouse.track){
- mousetrack(mouse.dx, mouse.dy, mouse.buttons, TK2MS(MACHP(0)->ticks));
- mouse.track = 0;
- mouse.dx = 0;
- mouse.dy = 0;
- }
- if(mouse.redraw && canlock(&cursor)){
- mouse.redraw = 0;
- cursoroff(0);
- mouse.redraw = cursoron(0);
- unlock(&cursor);
+ while(waserror())
+ ;
+ for(;;){
+ if(mouse.redraw){
+ mouse.redraw = 0;
+ cursoroff();
+ cursoron();
+ drawactive(1);
+ } else {
+ drawactive(0);
+ }
+ tsleep(&mouse.redrawr, shouldredraw, 0, 20*1000);
}
- drawactive(0);
}
static int
@@ -595,7 +595,6 @@ absmousetrack(int x, int y, int b, int msec)
lastb = mouse.buttons;
mouse.xy = Pt(x, y);
mouse.buttons = b;
- mouse.redraw = 1;
mouse.counter++;
mouse.msec = msec;
@@ -611,7 +610,8 @@ absmousetrack(int x, int y, int b, int msec)
mouse.qfull = 1;
}
wakeup(&mouse.r);
- drawactive(1);
+
+ mouseredraw();
}
/*
@@ -782,3 +782,9 @@ mouseresize(void)
wakeup(&mouse.r);
}
+void
+mouseredraw(void)
+{
+ mouse.redraw = 1;
+ wakeup(&mouse.redrawr);
+}
diff --git a/sys/src/9/port/portmkfile b/sys/src/9/port/portmkfile
index 2f5ab1d54..c796452db 100644
--- a/sys/src/9/port/portmkfile
+++ b/sys/src/9/port/portmkfile
@@ -81,6 +81,7 @@ devuart.$O: ../port/netif.h
devmouse.$O: screen.h /sys/include/memdraw.h
devdraw.$O: screen.h /sys/include/memdraw.h
screen.$O: screen.h /sys/include/memdraw.h
+swcursor.$O: screen.h /sys/include/memdraw.h
thwack.$O: ../port/thwack.h
unthwack.$O: ../port/thwack.h
devsdp.$O: ../port/thwack.h
diff --git a/sys/src/9/port/swcursor.c b/sys/src/9/port/swcursor.c
new file mode 100644
index 000000000..55ea014d0
--- /dev/null
+++ b/sys/src/9/port/swcursor.c
@@ -0,0 +1,133 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+
+#define Image IMAGE
+#include <draw.h>
+#include <memdraw.h>
+#include <cursor.h>
+#include "screen.h"
+
+extern Memimage* gscreen;
+
+/*
+ * Software cursor.
+ */
+static Memimage* swback; /* screen under cursor */
+static Memimage* swimg; /* cursor image */
+static Memimage* swmask; /* cursor mask */
+static Memimage* swimg1;
+static Memimage* swmask1;
+
+static Point swoffset;
+static Rectangle swrect; /* screen rectangle in swback */
+static Point swvispt; /* actual cursor location */
+static int swvisible; /* is the cursor visible? */
+
+/*
+ * called with drawlock locked for us, most of the time.
+ * kernel prints at inopportune times might mean we don't
+ * hold the lock, but memimagedraw is now reentrant so
+ * that should be okay: worst case we get cursor droppings.
+ */
+void
+swcursorhide(void)
+{
+ if(swvisible == 0)
+ return;
+ if(swback == nil || gscreen == nil)
+ return;
+ swvisible = 0;
+ memimagedraw(gscreen, swrect, swback, ZP, memopaque, ZP, S);
+ flushmemscreen(swrect);
+}
+
+void
+swcursoravoid(Rectangle r)
+{
+ if(swvisible && rectXrect(r, swrect)){
+ swcursorhide();
+ mouseredraw(); /* schedule cursor redraw after we release drawlock */
+ }
+}
+
+void
+swcursordraw(Point p)
+{
+ if(swvisible)
+ return;
+ if(swback == nil || swimg1 == nil || swmask1 == nil || gscreen == nil)
+ return;
+ assert(!canqlock(&drawlock));
+ swvispt = addpt(swoffset, p);
+ swrect = rectaddpt(Rect(0,0,16,16), swvispt);
+ memimagedraw(swback, swback->r, gscreen, swvispt, memopaque, ZP, S);
+ memimagedraw(gscreen, swrect, swimg1, ZP, swmask1, ZP, SoverD);
+ flushmemscreen(swrect);
+ swvisible = 1;
+}
+
+void
+swcursorload(Cursor *curs)
+{
+ uchar *ip, *mp;
+ int i, j, set, clr;
+
+ if(swimg == nil || swmask == nil || swimg1 == nil || swmask1 == nil)
+ return;
+ /*
+ * Build cursor image and mask.
+ * Image is just the usual cursor image
+ * but mask is a transparent alpha mask.
+ *
+ * The 16x16x8 memimages do not have
+ * padding at the end of their scan lines.
+ */
+ ip = byteaddr(swimg, ZP);
+ mp = byteaddr(swmask, ZP);
+ for(i=0; i<32; i++){
+ set = curs->set[i];
+ clr = curs->clr[i];
+ for(j=0x80; j; j>>=1){
+ *ip++ = set&j ? 0x00 : 0xFF;
+ *mp++ = (clr|set)&j ? 0xFF : 0x00;
+ }
+ }
+ swoffset = curs->offset;
+ memimagedraw(swimg1, swimg1->r, swimg, ZP, memopaque, ZP, S);
+ memimagedraw(swmask1, swmask1->r, swmask, ZP, memopaque, ZP, S);
+
+ mouseredraw();
+}
+
+void
+swcursorinit(void)
+{
+ if(gscreen == nil)
+ return;
+
+ if(swback){
+ freememimage(swback);
+ freememimage(swmask);
+ freememimage(swmask1);
+ freememimage(swimg);
+ freememimage(swimg1);
+ }
+ swback = allocmemimage(Rect(0,0,32,32), gscreen->chan);
+ swmask = allocmemimage(Rect(0,0,16,16), GREY8);
+ swmask1 = allocmemimage(Rect(0,0,16,16), GREY1);
+ swimg = allocmemimage(Rect(0,0,16,16), GREY8);
+ swimg1 = allocmemimage(Rect(0,0,16,16), GREY1);
+ if(swback == nil || swmask == nil || swmask1 == nil || swimg == nil || swimg1 == nil){
+ print("software cursor: allocmemimage fails\n");
+ return;
+ }
+ memfillcolor(swback, DTransparent);
+ memfillcolor(swmask, DOpaque);
+ memfillcolor(swmask1, DOpaque);
+ memfillcolor(swimg, DBlack);
+ memfillcolor(swimg1, DBlack);
+}