kernel: cleanup the software mouse cursor mess

The swcursor used a 32x32 image for saving/restoring
screen contents for no reason.

Add a doflush argument to swcursorhide(), so that
disabling software cursor with a double buffered
softscreen is properly hidden. The doflush parameter
should be set to 0 in all other cases as swcursordraw()
will flushes both (current and previours) locations.

Make sure swcursorinit() and swcursorhide() clear the
visibility flag, even when gscreen is nil.

Remove the cursor locking and just do everything within
the drawlock. All cursor functions such as curson(),
cursoff() and setcursor() will be called drawlock
locked. This also means &cursor can be read.

Fix devmouse cursor reads and writes. We now have the
global cursor variable that is only modified under
the drawlock. So copy under drawlock.

Move the pc software cursor implementation into vgasoft
driver, so screen.c does not need to handle it as
a special case.

Remove unused functions such as drawhasclients().
This commit is contained in:
cinap_lenrek 2020-04-10 17:12:51 +02:00
parent 7b309d2e28
commit 1fe3143e4c
30 changed files with 150 additions and 285 deletions

View file

@ -55,28 +55,21 @@ static void myscreenputs(char *s, int n);
static void screenputc(char *buf);
static void screenwin(void);
/* called from devmouse */
void
cursoron(void)
{
qlock(&drawlock);
lock(&cursor);
swcursorhide();
swcursorhide(0);
swcursordraw(mousexy());
unlock(&cursor);
qunlock(&drawlock);
}
void
cursoroff(void)
{
qlock(&drawlock);
lock(&cursor);
swcursorhide();
unlock(&cursor);
qunlock(&drawlock);
swcursorhide(0);
}
/* called from devmouse */
void
setcursor(Cursor* curs)
{

View file

@ -1,11 +1,6 @@
typedef struct Cursor Cursor;
typedef struct Cursorinfo Cursorinfo;
struct Cursorinfo {
Cursor;
Lock;
};
/* devmouse.c */
typedef struct Cursor Cursor;
extern Cursor cursor;
extern void mousetrack(int, int, int, ulong);
extern void absmousetrack(int, int, int, ulong);
extern Point mousexy(void);
@ -15,9 +10,6 @@ extern int m3mouseputc(Queue*, int);
extern int m5mouseputc(Queue*, int);
extern int mouseputc(Queue*, int);
extern Cursorinfo cursor;
extern Cursor arrow;
/* mouse.c */
extern void mousectl(Cmdbuf*);
extern void mouseresize(void);
@ -37,7 +29,7 @@ extern QLock drawlock;
#define ishwimage(i) 1 /* for ../port/devdraw.c */
/* swcursor.c */
void swcursorhide(void);
void swcursorhide(int);
void swcursoravoid(Rectangle);
void swcursordraw(Point);
void swcursorload(Cursor *);

View file

@ -189,24 +189,6 @@ static ulong rep(ulong, int);
static void screenputc(char *buf);
static void screenwin(void);
/*
* 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 */
static void
lcdoff(void)
{
@ -330,28 +312,21 @@ screenpower(int on)
blankscreen(on == 0);
}
/* called from devmouse */
void
cursoron(void)
{
qlock(&drawlock);
lock(&cursor);
swcursorhide();
swcursorhide(0);
swcursordraw(mousexy());
unlock(&cursor);
qunlock(&drawlock);
}
void
cursoroff(void)
{
qlock(&drawlock);
lock(&cursor);
swcursorhide();
unlock(&cursor);
qunlock(&drawlock);
swcursorhide(0);
}
/* called from devmouse */
void
setcursor(Cursor* curs)
{
@ -404,10 +379,7 @@ screeninit(void)
iprint("screen: frame buffer at %#p for %dx%d\n",
framebuf, oscreen.settings->wid, oscreen.settings->ht);
swenabled = 1;
swcursorinit(); /* needs gscreen set */
setcursor(&arrow);
first = 0;
}
}

View file

@ -1,22 +1,13 @@
typedef struct Cursor Cursor;
typedef struct Cursorinfo Cursorinfo;
typedef struct OScreen OScreen;
typedef struct Omap3fb Omap3fb;
typedef struct Settings Settings;
struct Cursorinfo
{
Cursor;
Lock;
};
extern Cursor arrow;
extern Cursorinfo cursor;
/* devmouse.c */
extern void mousetrack(int, int, int, ulong);
extern void absmousetrack(int, int, int, ulong);
extern Point mousexy(void);
extern Cursor cursor;
extern void mousetrack(int, int, int, ulong);
extern void absmousetrack(int, int, int, ulong);
extern Point mousexy(void);
extern void mouseaccelerate(int);
extern void mouseresize(void);
@ -33,15 +24,9 @@ extern int screenaperture(int, int);
extern Rectangle physgscreenr; /* actual monitor size */
extern void blankscreen(int);
extern void swcursorinit(void);
extern void swcursorhide(void);
extern void swcursoravoid(Rectangle);
extern void swcursorunhide(void);
/* devdraw.c */
extern void deletescreenimage(void);
extern void resetscreenimage(void);
extern int drawhasclients(void);
extern void setscreenimageclipr(Rectangle);
extern void drawflush(void);
extern QLock drawlock;
@ -49,7 +34,7 @@ extern QLock drawlock;
#define ishwimage(i) 0 /* for ../port/devdraw.c */
/* swcursor.c */
void swcursorhide(void);
void swcursorhide(int);
void swcursoravoid(Rectangle);
void swcursordraw(Point);
void swcursorload(Cursor *);

View file

@ -233,36 +233,28 @@ vgactl(Cmdbuf *cb)
if(scr->gscreen == nil)
error(Enoscreen);
if(strcmp(cb->f[1], "off") == 0){
lock(&cursor);
qlock(&drawlock);
cursoroff();
if(scr->cur){
if(scr->cur->disable)
scr->cur->disable(scr);
scr->cur = nil;
}
unlock(&cursor);
return;
}
if(strcmp(cb->f[1], "soft") == 0){
lock(&cursor);
swcursorinit();
if(scr->cur && scr->cur->disable)
scr->cur->disable(scr);
scr->cur = &swcursor;
if(scr->cur->enable)
scr->cur->enable(scr);
unlock(&cursor);
qunlock(&drawlock);
return;
}
for(i = 0; vgacur[i]; i++){
if(strcmp(cb->f[1], vgacur[i]->name))
continue;
lock(&cursor);
qlock(&drawlock);
cursoroff();
if(scr->cur && scr->cur->disable)
scr->cur->disable(scr);
scr->cur = vgacur[i];
if(scr->cur->enable)
scr->cur->enable(scr);
unlock(&cursor);
cursoron();
qunlock(&drawlock);
return;
}
break;
@ -319,7 +311,6 @@ vgactl(Cmdbuf *cb)
error("bad channel");
if(chantodepth(chan) != z)
error("depth, channel do not match");
cursoroff();
deletescreenimage();
if(screensize(x, y, z, chan))
error(Egreg);
@ -338,7 +329,6 @@ vgactl(Cmdbuf *cb)
error(Ebadarg);
if(!rectinrect(r, scr->gscreen->r))
error("physical screen bigger than virtual");
cursoroff();
deletescreenimage();
physgscreenr = r;
goto Resized;
@ -364,7 +354,6 @@ vgactl(Cmdbuf *cb)
y = scr->gscreen->r.max.y;
z = scr->gscreen->depth;
chan = scr->gscreen->chan;
cursoroff();
deletescreenimage();
if(screensize(x, y, z, chan))
error(Egreg);
@ -381,7 +370,6 @@ vgactl(Cmdbuf *cb)
scr->gscreen->clipr = panning ? scr->gscreen->r : physgscreenr;
vgascreenwin(scr);
resetscreenimage();
cursoron();
return;
case CMlinear:
@ -410,7 +398,6 @@ vgactl(Cmdbuf *cb)
break;
if(scr->gscreen == nil)
return;
cursoroff();
deletescreenimage();
goto Resized;

View file

@ -24,7 +24,7 @@ dev
bridge netif log
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
draw screen vga vgax swcursor
draw screen vga vgax vgasoft
mouse mouse
kbd
vga
@ -114,6 +114,7 @@ misc
uartisa
uartpci pci
vgasoft =cur swcursor
vga3dfx +cur
vgaark2000pv +cur
vgabt485 =cur

View file

@ -13,6 +13,8 @@
#include <cursor.h>
#include "screen.h"
extern VGAcur vgasoftcur;
Rectangle physgscreenr;
Memimage *gscreen;
@ -82,7 +84,6 @@ screensize(int x, int y, int, ulong chan)
poperror();
drawcmap();
swcursorinit();
qunlock(&drawlock);
poperror();
@ -240,11 +241,9 @@ getcolor(ulong p, ulong* pr, ulong* pg, ulong* pb)
}
p &= x;
lock(&cursor);
*pr = scr->colormap[p][0];
*pg = scr->colormap[p][1];
*pb = scr->colormap[p][2];
unlock(&cursor);
}
int
@ -256,7 +255,6 @@ setpalette(ulong p, ulong r, ulong g, ulong b)
scr = &vgascreen[0];
d = scr->palettedepth;
lock(&cursor);
scr->colormap[p][0] = r;
scr->colormap[p][1] = g;
scr->colormap[p][2] = b;
@ -264,7 +262,6 @@ setpalette(ulong p, ulong r, ulong g, ulong b)
vgao(Pdata, r>>(32-d));
vgao(Pdata, g>>(32-d));
vgao(Pdata, b>>(32-d));
unlock(&cursor);
return ~0;
}
@ -301,41 +298,6 @@ 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
swmove(VGAscr*, Point p)
{
swcursorhide();
swcursordraw(p);
return 0;
}
VGAcur swcursor =
{
"soft",
swenable,
swdisable,
swload,
swmove,
};
void
cursoron(void)
{
@ -344,16 +306,8 @@ cursoron(void)
scr = &vgascreen[0];
cur = scr->cur;
if(cur == nil || cur->move == nil)
return;
if(cur == &swcursor)
qlock(&drawlock);
lock(&cursor);
cur->move(scr, mousexy());
unlock(&cursor);
if(cur == &swcursor)
qunlock(&drawlock);
if(cur && cur->move)
cur->move(scr, mousexy());
}
void
@ -365,12 +319,12 @@ void
setcursor(Cursor* curs)
{
VGAscr *scr;
VGAcur *cur;
scr = &vgascreen[0];
if(scr->cur == nil || scr->cur->load == nil)
return;
scr->cur->load(scr, curs);
cur = scr->cur;
if(cur && cur->load)
cur->load(scr, curs);
}
int hwaccel = 0;
@ -395,7 +349,7 @@ hwdraw(Memdrawparam *par)
src = nil;
if((mask = par->mask) && mask->data == nil)
mask = nil;
if(scr->cur == &swcursor){
if(scr->cur == &vgasoftcur){
if(dst->data->bdata == scrd->bdata)
swcursoravoid(par->r);
if(src && src->data->bdata == scrd->bdata)
@ -687,11 +641,8 @@ bootscreeninit(void)
vgaimageinit(chan);
vgascreenwin(scr);
/* turn mouse cursor on */
swcursorinit();
scr->cur = &swcursor;
scr->cur = &vgasoftcur;
scr->cur->enable(scr);
cursoron();
conf.monitor = 1;
}

View file

@ -1,11 +1,6 @@
typedef struct Cursor Cursor;
typedef struct Cursorinfo Cursorinfo;
struct Cursorinfo {
Cursor;
Lock;
};
/* devmouse.c */
typedef struct Cursor Cursor;
extern Cursor cursor;
extern void mousetrack(int, int, int, ulong);
extern void absmousetrack(int, int, int, ulong);
extern Point mousexy(void);
@ -15,9 +10,6 @@ extern int m3mouseputc(Queue*, int);
extern int m5mouseputc(Queue*, int);
extern int mouseputc(Queue*, int);
extern Cursorinfo cursor;
extern Cursor arrow;
/*
* Generic VGA registers.
*/
@ -134,11 +126,11 @@ extern void mouseresize(void);
extern void mouseredraw(void);
/* screen.c */
extern int hwaccel; /* use hw acceleration */
extern int hwblank; /* use hw blanking */
extern int panning; /* use virtual screen panning */
extern void addvgaseg(char*, ulong, ulong);
extern Memdata* attachscreen(Rectangle*, ulong*, int*, int*, int*);
extern int hwaccel; /* use hw acceleration */
extern int hwblank; /* use hw blanking */
extern int panning; /* use virtual screen panning */
extern void addvgaseg(char*, ulong, ulong);
extern Memdata* attachscreen(Rectangle*, ulong*, int*, int*, int*);
extern void flushmemscreen(Rectangle);
extern void cursoron(void);
extern void cursoroff(void);
@ -148,20 +140,12 @@ extern int screenaperture(int, int);
extern Rectangle physgscreenr; /* actual monitor size */
extern void blankscreen(int);
extern char* rgbmask2chan(char *buf, int depth, u32int rm, u32int gm, u32int bm);
extern void bootscreeninit(void);
extern void bootscreenconf(VGAscr*);
extern VGAcur swcursor;
extern void swcursorinit(void);
extern void swcursorhide(void);
extern void swcursoravoid(Rectangle);
extern void swcursorunhide(void);
/* devdraw.c */
extern void deletescreenimage(void);
extern void resetscreenimage(void);
extern int drawhasclients(void);
extern void setscreenimageclipr(Rectangle);
extern void drawflush(void);
extern QLock drawlock;
@ -171,15 +155,13 @@ extern void vgascreenwin(VGAscr*);
extern void vgaimageinit(ulong);
extern void vgalinearpci(VGAscr*);
extern void vgalinearaddr(VGAscr*, ulong, int);
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 swcursorhide(int);
void swcursoravoid(Rectangle);
void swcursordraw(Point);
void swcursorload(Cursor *);

View file

@ -168,7 +168,7 @@ tdfxcurenable(VGAscr* scr)
/*
* Load, locate and enable the 64x64 cursor in X11 mode.
*/
tdfxcurload(scr, &arrow);
tdfxcurload(scr, &cursor);
tdfxcurmove(scr, ZP);
cursor3dfx->vidProcCfg |= 0x08000002;
}

View file

@ -186,7 +186,7 @@ clgd546xcurenable(VGAscr* scr)
/*
* Load, locate and enable the 64x64 cursor.
*/
clgd546xcurload(scr, &arrow);
clgd546xcurload(scr, &cursor);
clgd546xcurmove(scr, ZP);
cursor546x->enable = 1;
}

View file

@ -181,7 +181,7 @@ cyber938xcurenable(VGAscr* scr)
* enable is bit 7). Bit 3 needs to be set on 9382
* chips otherwise even the white bits are black.
*/
cyber938xcurload(scr, &arrow);
cyber938xcurload(scr, &cursor);
cyber938xcurmove(scr, ZP);
vgaxo(Crtx, 0x50, CursorON);
}

View file

@ -91,7 +91,7 @@ geodecurenable(VGAscr* scr)
{
geodeenable(scr);
if(!scr->mmio) return;
geodecurload(scr, &arrow);
geodecurload(scr, &cursor);
geodecurmove(scr, ZP);
((ulong*)scr->mmio)[DC_UNLOCK] = DC_UNLOCKVALUE;
((ulong*)scr->mmio)[DC_CURS_ST_OFFSET] = scr->storage;

View file

@ -200,7 +200,7 @@ hiqvideocurenable(VGAscr* scr)
* Load, locate and enable the 32x32 cursor.
* Cursor enable in Xr80 better be set already.
*/
hiqvideocurload(scr, &arrow);
hiqvideocurload(scr, &cursor);
hiqvideocurmove(scr, ZP);
hiqvideoxo(Xrx, 0xA0, 0x11);
}

View file

@ -210,7 +210,7 @@ i81xcurenable(VGAscr* scr)
/*
* Load, locate and enable the 32x32 cursor in 2bpp mode.
*/
i81xcurload(scr, &arrow);
i81xcurload(scr, &cursor);
i81xcurmove(scr, ZP);
}

View file

@ -198,7 +198,7 @@ igfxcurenable(VGAscr* scr)
int i;
igfxenable(scr);
igfxcurload(scr, &arrow);
igfxcurload(scr, &cursor);
igfxcurmove(scr, ZP);
for(i=0; i<NPIPE; i++){

View file

@ -603,7 +603,7 @@ mach64xxcurenable(VGAscr* scr)
/*
* Load, locate and enable the 64x64 cursor.
*/
mach64xxcurload(scr, &arrow);
mach64xxcurload(scr, &cursor);
mach64xxcurmove(scr, ZP);
iow32(scr, GenTestCntl, 0x80|r);
}

View file

@ -202,7 +202,7 @@ tvp3026enable(VGAscr* scr)
* Load, locate and enable the
* 64x64 cursor in 3-colour mode.
*/
tvp3026load(scr, &arrow);
tvp3026load(scr, &cursor);
tvp3026move(scr, ZP);
*(tvp3026+Cctl) = 0x01;
}

View file

@ -302,7 +302,7 @@ dac4xxenable(VGAscr *scr)
* Load, locate and enable the
* 64x64 cursor in X11 mode.
*/
dac4xxload(scr, &arrow);
dac4xxload(scr, &cursor);
dac4xxmove(scr, ZP);
}

View file

@ -230,7 +230,7 @@ neomagiccurenable(VGAscr* scr)
/*
* Load, locate and enable the 64x64 cursor.
*/
neomagiccurload(scr, &arrow);
neomagiccurload(scr, &cursor);
neomagiccurmove(scr, ZP);
cursornm->enable = 1;
}

View file

@ -232,7 +232,7 @@ nvidiacurenable(VGAscr* scr)
vgaxo(Crtx, 0x1F, 0x57);
nvidiacurload(scr, &arrow);
nvidiacurload(scr, &cursor);
nvidiacurmove(scr, ZP);
vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) | 0x01);

View file

@ -201,7 +201,7 @@ radeoncurenable(VGAscr *scr)
radeoncurdisable(scr);
storage = scr->apsize - 1*Meg;
scr->storage = (uintptr)KADDR(scr->paddr + storage);
radeoncurload(scr, &arrow);
radeoncurload(scr, &cursor);
radeoncurmove(scr, ZP);
OUTREGP(scr->mmio, CRTC_GEN_CNTL, CRTC_CUR_EN | 2<<20,

View file

@ -317,7 +317,7 @@ s3enable(VGAscr* scr)
* Load, locate and enable the cursor
* in Microsoft Windows format.
*/
s3load(scr, &arrow);
s3load(scr, &cursor);
s3move(scr, ZP);
vgaxo(Crtx, 0x55, vgaxi(Crtx, 0x55) & ~0x10);
s3vsyncactive();

50
sys/src/9/pc/vgasoft.c Normal file
View file

@ -0,0 +1,50 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "ureg.h"
#include "../port/error.h"
#define Image IMAGE
#include <draw.h>
#include <memdraw.h>
#include <cursor.h>
#include "screen.h"
static void
swenable(VGAscr*)
{
swcursorinit();
swcursorload(&cursor);
}
static void
swdisable(VGAscr*)
{
swcursorhide(1);
}
static void
swload(VGAscr*, Cursor *curs)
{
swcursorload(curs);
}
static int
swmove(VGAscr*, Point p)
{
swcursorhide(0);
swcursordraw(p);
return 0;
}
VGAcur vgasoftcur =
{
"soft",
swenable,
swdisable,
swload,
swmove,
};

View file

@ -261,7 +261,7 @@ t2r4curenable(VGAscr* scr)
/*
* Load, locate and enable the cursor, 64x64, mode 2.
*/
t2r4curload(scr, &arrow);
t2r4curload(scr, &cursor);
t2r4curmove(scr, ZP);
t2r4xo(scr, CursorCtl, CursorMode);
}

View file

@ -23,7 +23,7 @@ dev
bridge netif log
ip arp chandial ip ipv6 ipaux iproute netlog ethermedium nullmedium pktmedium inferno
draw screen vga vgax swcursor
draw screen vga vgax vgasoft
mouse mouse
kbd
vga
@ -112,6 +112,7 @@ misc
uartisa
uartpci pci
vgasoft =cur swcursor
# vga3dfx +cur
# vgaark2000pv +cur
# vgabt485 =cur

View file

@ -799,17 +799,6 @@ drawclientop(Client *cl)
return op;
}
int
drawhasclients(void)
{
/*
* if draw has ever been used, we can't resize the frame buffer,
* even if all clients have exited (nclients is cumulative); it's too
* hard to make work.
*/
return sdraw.nclient != 0;
}
Client*
drawclientofpath(ulong path)
{

View file

@ -71,10 +71,7 @@ static Cmdtab mousectlmsg[] =
};
Mouseinfo mouse;
Cursorinfo cursor;
Cursor curs;
void Cursortocursor(Cursor*);
void mouseblankscreen(int);
int mousechanged(void*);
void mouseredraw(void);
@ -105,7 +102,7 @@ static ulong blanktime = 30; /* in minutes; a half hour */
extern Memimage* gscreen;
Cursor arrow = {
Cursor arrow = {
{ -1, -1 },
{ 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C,
0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04,
@ -118,16 +115,9 @@ Cursor arrow = {
0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00,
},
};
Cursor cursor;
static void
mousereset(void)
{
if(!conf.monitor)
return;
curs = arrow;
Cursortocursor(&arrow);
}
static void Cursortocursor(Cursor*);
static int
mousedevgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp)
@ -147,12 +137,8 @@ mouseinit(void)
{
if(!conf.monitor)
return;
curs = arrow;
Cursortocursor(&arrow);
cursoron();
mousetime = seconds();
Cursortocursor(&arrow);
kproc("mouse", mouseproc, 0);
}
@ -232,10 +218,7 @@ mouseclose(Chan *c)
case Qcursor:
if(decref(&mouse) != 0)
return;
cursoroff();
curs = arrow;
Cursortocursor(&arrow);
cursoron();
}
}
@ -246,6 +229,7 @@ mouseread(Chan *c, void *va, long n, vlong off)
char buf[1+4*12+1];
uchar *p;
ulong offset = off;
Cursor curs;
Mousestate m;
int b;
@ -259,6 +243,11 @@ mouseread(Chan *c, void *va, long n, vlong off)
return 0;
if(n < 2*4+2*2*16)
error(Eshort);
qlock(&drawlock);
memmove(&curs, &cursor, sizeof(Cursor));
qunlock(&drawlock);
n = 2*4+2*2*16;
BPLONG(p+0, curs.offset.x);
BPLONG(p+4, curs.offset.y);
@ -360,6 +349,7 @@ mousewrite(Chan *c, void *va, long n, vlong)
Point pt;
Cmdbuf *cb;
Cmdtab *ct;
Cursor curs;
char buf[64];
int b, z, msec;
Mousestate *m;
@ -370,19 +360,16 @@ mousewrite(Chan *c, void *va, long n, vlong)
error(Eisdir);
case Qcursor:
cursoroff();
if(n < 2*4+2*2*16){
curs = arrow;
Cursortocursor(&arrow);
}else{
n = 2*4+2*2*16;
curs.offset.x = BGLONG(p+0);
curs.offset.y = BGLONG(p+4);
memmove(curs.clr, p+8, 2*16);
memmove(curs.set, p+40, 2*16);
Cursortocursor(&curs);
return n;
}
cursoron();
n = 2*4+2*2*16;
curs.offset.x = BGLONG(p+0);
curs.offset.y = BGLONG(p+4);
memmove(curs.clr, p+8, 2*16);
memmove(curs.set, p+40, 2*16);
Cursortocursor(&curs);
return n;
case Qmousectl:
@ -498,7 +485,7 @@ Dev mousedevtab = {
'm',
"mouse",
mousereset,
devreset,
mouseinit,
devshutdown,
mouseattach,
@ -515,14 +502,14 @@ Dev mousedevtab = {
devwstat,
};
void
static void
Cursortocursor(Cursor *c)
{
qlock(&drawlock);
lock(&cursor);
memmove(&cursor.Cursor, c, sizeof(Cursor));
cursoroff();
memmove(&cursor, c, sizeof(Cursor));
setcursor(c);
unlock(&cursor);
cursoron();
qunlock(&drawlock);
}
@ -558,8 +545,11 @@ mouseproc(void*)
for(;;){
sleep(&mouse.redrawr, shouldredraw, nil);
mouse.redraw = 0;
qlock(&drawlock);
cursoroff();
cursoron();
qunlock(&drawlock);
}
}

View file

@ -34,21 +34,25 @@ static int swvisible; /* is the cursor visible? */
* that should be okay: worst case we get cursor droppings.
*/
void
swcursorhide(void)
swcursorhide(int doflush)
{
if(swvisible == 0)
return;
swvisible = 0;
if(swback == nil || gscreen == nil)
return;
swvisible = 0;
memimagedraw(gscreen, swrect, swback, ZP, memopaque, ZP, S);
if(doflush){
flushmemscreen(swrect);
swrect = ZR;
}
}
void
swcursoravoid(Rectangle r)
{
if(swvisible && rectXrect(r, swrect)){
swcursorhide();
swcursorhide(0);
mouseredraw(); /* schedule cursor redraw after we release drawlock */
}
}
@ -62,10 +66,9 @@ swcursordraw(Point p)
return;
if(swback == nil || swimg1 == nil || swmask1 == nil || gscreen == nil)
return;
assert(!canqlock(&drawlock));
swvispt = addpt(swoffset, p);
flushr = swrect;
swrect = rectaddpt(Rect(0,0,16,16), swvispt);
swrect = rectaddpt(swimg1->r, swvispt);
combinerect(&flushr, swrect);
memimagedraw(swback, swback->r, gscreen, swvispt, memopaque, ZP, S);
memimagedraw(gscreen, swrect, swimg1, ZP, swmask1, ZP, SoverD);
@ -102,13 +105,12 @@ swcursorload(Cursor *curs)
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)
{
swvisible = 0;
if(gscreen == nil)
return;
@ -119,7 +121,7 @@ swcursorinit(void)
freememimage(swimg);
freememimage(swimg1);
}
swback = allocmemimage(Rect(0,0,32,32), gscreen->chan);
swback = allocmemimage(Rect(0,0,16,16), 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);

View file

@ -1,11 +1,6 @@
typedef struct Cursor Cursor;
typedef struct Cursorinfo Cursorinfo;
struct Cursorinfo {
Cursor;
Lock;
};
/* devmouse.c */
typedef struct Cursor Cursor;
extern Cursor cursor;
extern void mousetrack(int, int, int, ulong);
extern void absmousetrack(int, int, int, ulong);
extern Point mousexy(void);
@ -15,9 +10,6 @@ extern int m3mouseputc(Queue*, int);
extern int m5mouseputc(Queue*, int);
extern int mouseputc(Queue*, int);
extern Cursorinfo cursor;
extern Cursor arrow;
/* mouse.c */
extern void mousectl(Cmdbuf*);
extern void mouseresize(void);
@ -35,10 +27,3 @@ extern void setcursor(Cursor*);
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);

View file

@ -1,11 +1,6 @@
typedef struct Cursor Cursor;
typedef struct Cursorinfo Cursorinfo;
struct Cursorinfo {
Cursor;
Lock;
};
/* devmouse.c */
typedef struct Cursor Cursor;
extern Cursor cursor;
extern void mousetrack(int, int, int, ulong);
extern void absmousetrack(int, int, int, ulong);
extern Point mousexy(void);
@ -15,9 +10,6 @@ extern int m3mouseputc(Queue*, int);
extern int m5mouseputc(Queue*, int);
extern int mouseputc(Queue*, int);
extern Cursorinfo cursor;
extern Cursor arrow;
/* mouse.c */
extern void mousectl(Cmdbuf*);
extern void mouseresize(void);
@ -37,10 +29,3 @@ extern void resetscreenimage(void);
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);