From 1fe3143e4c43ce2c74e0cfdd70b1bd556bbb9e1b Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Fri, 10 Apr 2020 17:12:51 +0200 Subject: [PATCH] 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(). --- sys/src/9/bcm/screen.c | 15 +++----- sys/src/9/bcm/screen.h | 14 ++------ sys/src/9/omap/screen.c | 36 +++---------------- sys/src/9/omap/screen.h | 25 +++----------- sys/src/9/pc/devvga.c | 27 ++++----------- sys/src/9/pc/pc | 3 +- sys/src/9/pc/screen.c | 69 ++++++------------------------------- sys/src/9/pc/screen.h | 34 +++++------------- sys/src/9/pc/vga3dfx.c | 2 +- sys/src/9/pc/vgaclgd546x.c | 2 +- sys/src/9/pc/vgacyber938x.c | 2 +- sys/src/9/pc/vgageode.c | 2 +- sys/src/9/pc/vgahiqvideo.c | 2 +- sys/src/9/pc/vgai81x.c | 2 +- sys/src/9/pc/vgaigfx.c | 2 +- sys/src/9/pc/vgamach64xx.c | 2 +- sys/src/9/pc/vgamga2164w.c | 2 +- sys/src/9/pc/vgamga4xx.c | 2 +- sys/src/9/pc/vganeomagic.c | 2 +- sys/src/9/pc/vganvidia.c | 2 +- sys/src/9/pc/vgaradeon.c | 2 +- sys/src/9/pc/vgas3.c | 2 +- sys/src/9/pc/vgasoft.c | 50 +++++++++++++++++++++++++++ sys/src/9/pc/vgat2r4.c | 2 +- sys/src/9/pc64/pc64 | 3 +- sys/src/9/port/devdraw.c | 11 ------ sys/src/9/port/devmouse.c | 62 ++++++++++++++------------------- sys/src/9/port/swcursor.c | 18 +++++----- sys/src/9/sgi/screen.h | 19 ++-------- sys/src/9/zynq/screen.h | 19 ++-------- 30 files changed, 150 insertions(+), 285 deletions(-) create mode 100644 sys/src/9/pc/vgasoft.c diff --git a/sys/src/9/bcm/screen.c b/sys/src/9/bcm/screen.c index 53079a13f..a103f45ba 100644 --- a/sys/src/9/bcm/screen.c +++ b/sys/src/9/bcm/screen.c @@ -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) { diff --git a/sys/src/9/bcm/screen.h b/sys/src/9/bcm/screen.h index 0e9da4d3c..40e8358bf 100644 --- a/sys/src/9/bcm/screen.h +++ b/sys/src/9/bcm/screen.h @@ -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 *); diff --git a/sys/src/9/omap/screen.c b/sys/src/9/omap/screen.c index 0a4e005c5..0e9d2f0dc 100644 --- a/sys/src/9/omap/screen.c +++ b/sys/src/9/omap/screen.c @@ -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; } } diff --git a/sys/src/9/omap/screen.h b/sys/src/9/omap/screen.h index d06f83863..287e2ff8c 100644 --- a/sys/src/9/omap/screen.h +++ b/sys/src/9/omap/screen.h @@ -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 *); diff --git a/sys/src/9/pc/devvga.c b/sys/src/9/pc/devvga.c index a5a6f9b4e..11f370302 100644 --- a/sys/src/9/pc/devvga.c +++ b/sys/src/9/pc/devvga.c @@ -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; diff --git a/sys/src/9/pc/pc b/sys/src/9/pc/pc index 68e2e5e33..e4171f127 100644 --- a/sys/src/9/pc/pc +++ b/sys/src/9/pc/pc @@ -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 diff --git a/sys/src/9/pc/screen.c b/sys/src/9/pc/screen.c index b3a9f5cc9..2242494b6 100644 --- a/sys/src/9/pc/screen.c +++ b/sys/src/9/pc/screen.c @@ -13,6 +13,8 @@ #include #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; } diff --git a/sys/src/9/pc/screen.h b/sys/src/9/pc/screen.h index 0774f87c1..d852e5ad5 100644 --- a/sys/src/9/pc/screen.h +++ b/sys/src/9/pc/screen.h @@ -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 *); diff --git a/sys/src/9/pc/vga3dfx.c b/sys/src/9/pc/vga3dfx.c index 80cec38f3..1b4420c6b 100644 --- a/sys/src/9/pc/vga3dfx.c +++ b/sys/src/9/pc/vga3dfx.c @@ -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; } diff --git a/sys/src/9/pc/vgaclgd546x.c b/sys/src/9/pc/vgaclgd546x.c index efaccc2a5..5713d9ee9 100644 --- a/sys/src/9/pc/vgaclgd546x.c +++ b/sys/src/9/pc/vgaclgd546x.c @@ -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; } diff --git a/sys/src/9/pc/vgacyber938x.c b/sys/src/9/pc/vgacyber938x.c index c95d4e996..3df93896c 100644 --- a/sys/src/9/pc/vgacyber938x.c +++ b/sys/src/9/pc/vgacyber938x.c @@ -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); } diff --git a/sys/src/9/pc/vgageode.c b/sys/src/9/pc/vgageode.c index a6346e5b1..eee9fd919 100644 --- a/sys/src/9/pc/vgageode.c +++ b/sys/src/9/pc/vgageode.c @@ -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; diff --git a/sys/src/9/pc/vgahiqvideo.c b/sys/src/9/pc/vgahiqvideo.c index 9400580b5..824d5db0c 100644 --- a/sys/src/9/pc/vgahiqvideo.c +++ b/sys/src/9/pc/vgahiqvideo.c @@ -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); } diff --git a/sys/src/9/pc/vgai81x.c b/sys/src/9/pc/vgai81x.c index 0fbd2331e..f0e6ae933 100644 --- a/sys/src/9/pc/vgai81x.c +++ b/sys/src/9/pc/vgai81x.c @@ -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); } diff --git a/sys/src/9/pc/vgaigfx.c b/sys/src/9/pc/vgaigfx.c index 8702c29ee..34bc424e2 100644 --- a/sys/src/9/pc/vgaigfx.c +++ b/sys/src/9/pc/vgaigfx.c @@ -198,7 +198,7 @@ igfxcurenable(VGAscr* scr) int i; igfxenable(scr); - igfxcurload(scr, &arrow); + igfxcurload(scr, &cursor); igfxcurmove(scr, ZP); for(i=0; ienable = 1; } diff --git a/sys/src/9/pc/vganvidia.c b/sys/src/9/pc/vganvidia.c index 6e5e9694e..71274c872 100644 --- a/sys/src/9/pc/vganvidia.c +++ b/sys/src/9/pc/vganvidia.c @@ -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); diff --git a/sys/src/9/pc/vgaradeon.c b/sys/src/9/pc/vgaradeon.c index 188be5f8b..7d4af0875 100644 --- a/sys/src/9/pc/vgaradeon.c +++ b/sys/src/9/pc/vgaradeon.c @@ -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, diff --git a/sys/src/9/pc/vgas3.c b/sys/src/9/pc/vgas3.c index a948b3154..95cd58f30 100644 --- a/sys/src/9/pc/vgas3.c +++ b/sys/src/9/pc/vgas3.c @@ -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(); diff --git a/sys/src/9/pc/vgasoft.c b/sys/src/9/pc/vgasoft.c new file mode 100644 index 000000000..a29355c19 --- /dev/null +++ b/sys/src/9/pc/vgasoft.c @@ -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 +#include +#include +#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, +}; diff --git a/sys/src/9/pc/vgat2r4.c b/sys/src/9/pc/vgat2r4.c index 14d49dd70..4ef28042b 100644 --- a/sys/src/9/pc/vgat2r4.c +++ b/sys/src/9/pc/vgat2r4.c @@ -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); } diff --git a/sys/src/9/pc64/pc64 b/sys/src/9/pc64/pc64 index ed0cf6d03..6e03dc00e 100644 --- a/sys/src/9/pc64/pc64 +++ b/sys/src/9/pc64/pc64 @@ -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 diff --git a/sys/src/9/port/devdraw.c b/sys/src/9/port/devdraw.c index 259d6ddf3..a80916765 100644 --- a/sys/src/9/port/devdraw.c +++ b/sys/src/9/port/devdraw.c @@ -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) { diff --git a/sys/src/9/port/devmouse.c b/sys/src/9/port/devmouse.c index e8433ef5f..940e8ef97 100644 --- a/sys/src/9/port/devmouse.c +++ b/sys/src/9/port/devmouse.c @@ -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); } } diff --git a/sys/src/9/port/swcursor.c b/sys/src/9/port/swcursor.c index 75b658460..8161728e8 100644 --- a/sys/src/9/port/swcursor.c +++ b/sys/src/9/port/swcursor.c @@ -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); diff --git a/sys/src/9/sgi/screen.h b/sys/src/9/sgi/screen.h index b5ab1c9ba..9e1687507 100644 --- a/sys/src/9/sgi/screen.h +++ b/sys/src/9/sgi/screen.h @@ -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); diff --git a/sys/src/9/zynq/screen.h b/sys/src/9/zynq/screen.h index 1ea1a24d7..fdedeb7c4 100644 --- a/sys/src/9/zynq/screen.h +++ b/sys/src/9/zynq/screen.h @@ -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);