M alphapc/screen.c => alphapc/screen.c +1 -532
@@ 1,532 1,1 @@
-#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"
-
-#define RGB2K(r,g,b) ((156763*(r)+307758*(g)+59769*(b))>>19)
-
-Point ZP = {0, 0};
-
-Rectangle physgscreenr;
-
-Memdata gscreendata;
-Memimage *gscreen;
-
-VGAscr vgascreen[1];
-
-Cursor arrow = {
- { -1, -1 },
- { 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C,
- 0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04,
- 0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04,
- 0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40,
- },
- { 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0,
- 0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8,
- 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8,
- 0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00,
- },
-};
-
-int
-screensize(int x, int y, int z, ulong chan)
-{
- VGAscr *scr;
-
- memimageinit();
- scr = &vgascreen[0];
-
- /*
- * BUG: need to check if any xalloc'ed memory needs to
- * be given back if aperture is set.
- */
- if(scr->aperture == 0){
- int width = (x*z)/BI2WD;
-
- gscreendata.bdata = xalloc(width*BY2WD*y);
- if(gscreendata.bdata == 0)
- error("screensize: vga soft memory");
- memset(gscreendata.bdata, Backgnd, width*BY2WD*y);
- scr->useflush = 1;
-
- scr->aperture = PADDR(arch->pcimem(0xA0000, 1<<16));
- scr->apsize = 1<<16;
- }
- else
- gscreendata.bdata = KADDR(scr->aperture);
-
- if(gscreen)
- freememimage(gscreen);
-
- gscreen = allocmemimaged(Rect(0,0,x,y), chan, &gscreendata);
- vgaimageinit(chan);
- if(gscreen == nil)
- return -1;
-
-/* memset(gscreen->data->bdata, 0x15, (x*y*z+7)/8); /* RSC BUG */
- memfillcolor(gscreen, DRed);
-
- scr->palettedepth = 6; /* default */
- scr->gscreendata = &gscreendata;
- scr->memdefont = getmemdefont();
- scr->gscreen = gscreen;
-
- physgscreenr = gscreen->r;
-
- drawcmap();
- return 0;
-}
-
-int
-screenaperture(int size, int align)
-{
- VGAscr *scr;
- ulong aperture;
-
- scr = &vgascreen[0];
-
- if(size == 0){
- if(scr->aperture && scr->isupamem)
- upafree(scr->aperture, scr->apsize);
- scr->aperture = 0;
- scr->isupamem = 0;
- return 0;
- }
- if(scr->dev && scr->dev->linear){
- aperture = scr->dev->linear(scr, &size, &align);
- if(aperture == 0)
- return 1;
- }else{
- aperture = upamalloc(0, size, align);
- if(aperture == 0)
- return 1;
-
- if(scr->aperture && scr->isupamem)
- upafree(scr->aperture, scr->apsize);
- scr->isupamem = 1;
- }
-
- scr->aperture = aperture;
- scr->apsize = size;
-
- return 0;
-}
-
-uchar*
-attachscreen(Rectangle* r, ulong* chan, int* d, int* width, int *softscreen)
-{
- VGAscr *scr;
-
- scr = &vgascreen[0];
- if(scr->gscreen == nil || scr->gscreendata == nil)
- return nil;
-
- *r = scr->gscreen->r;
- *chan = scr->gscreen->chan;
- *d = scr->gscreen->depth;
- *width = scr->gscreen->width;
- *softscreen = scr->useflush;
-
- return scr->gscreendata->bdata;
-}
-
-/*
- * It would be fair to say that this doesn't work for >8-bit screens.
- */
-void
-flushmemscreen(Rectangle r)
-{
- VGAscr *scr;
- uchar *sp, *disp, *sdisp, *edisp;
- int y, len, incs, off, page;
-
- scr = &vgascreen[0];
- if(scr->gscreen == nil || scr->useflush == 0)
- return;
- if(scr->dev == nil || scr->dev->page == nil)
- return;
-
- if(rectclip(&r, scr->gscreen->r) == 0)
- return;
-
- incs = scr->gscreen->width * BY2WD;
-
- switch(scr->gscreen->depth){
- default:
- len = 0;
- panic("flushmemscreen: depth\n");
- break;
- case 8:
- len = Dx(r);
- break;
- }
- if(len < 1)
- return;
-
- off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x*scr->gscreen->depth)/8;
- page = off/scr->apsize;
- off %= scr->apsize;
- disp = KADDR(scr->aperture);
- sdisp = disp+off;
- edisp = disp+scr->apsize;
-
- off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x*scr->gscreen->depth)/8;
-
- sp = scr->gscreendata->bdata + off;
-
- scr->dev->page(scr, page);
- for(y = r.min.y; y < r.max.y; y++) {
- if(sdisp + incs < edisp) {
- memmove(sdisp, sp, len);
- sp += incs;
- sdisp += incs;
- }
- else {
- off = edisp - sdisp;
- page++;
- if(off <= len){
- if(off > 0)
- memmove(sdisp, sp, off);
- scr->dev->page(scr, page);
- if(len - off > 0)
- memmove(disp, sp+off, len - off);
- }
- else {
- memmove(sdisp, sp, len);
- scr->dev->page(scr, page);
- }
- sp += incs;
- sdisp += incs - scr->apsize;
- }
- }
-}
-
-void
-getcolor(ulong p, ulong* pr, ulong* pg, ulong* pb)
-{
- VGAscr *scr;
- ulong x;
-
- scr = &vgascreen[0];
- if(scr->gscreen == nil)
- return;
-
- switch(scr->gscreen->depth){
- default:
- x = 0x0F;
- break;
- case 8:
- x = 0xFF;
- break;
- }
- p &= x;
-
- lock(&cursor);
- *pr = scr->colormap[p][0];
- *pg = scr->colormap[p][1];
- *pb = scr->colormap[p][2];
- unlock(&cursor);
-}
-
-int
-setpalette(ulong p, ulong r, ulong g, ulong b)
-{
- VGAscr *scr;
- int d;
-
- scr = &vgascreen[0];
- d = scr->palettedepth;
-
- lock(&cursor);
- scr->colormap[p][0] = r;
- scr->colormap[p][1] = g;
- scr->colormap[p][2] = b;
- vgao(PaddrW, p);
- vgao(Pdata, r>>(32-d));
- vgao(Pdata, g>>(32-d));
- vgao(Pdata, b>>(32-d));
- unlock(&cursor);
-
- return ~0;
-}
-
-/*
- * On some video cards (e.g. Mach64), the palette is used as the
- * DAC registers for >8-bit modes. We don't want to set them when the user
- * is trying to set a colormap and the card is in one of these modes.
- */
-int
-setcolor(ulong p, ulong r, ulong g, ulong b)
-{
- VGAscr *scr;
- int x;
-
- scr = &vgascreen[0];
- if(scr->gscreen == nil)
- return 0;
-
- switch(scr->gscreen->depth){
- case 1:
- case 2:
- case 4:
- x = 0x0F;
- break;
- case 8:
- x = 0xFF;
- break;
- default:
- return 0;
- }
- p &= x;
-
- return setpalette(p, r, g, b);
-}
-
-int
-cursoron(int dolock)
-{
- VGAscr *scr;
- int v;
-
- 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);
-
- return v;
-}
-
-void
-cursoroff(int)
-{
-}
-
-void
-setcursor(Cursor* curs)
-{
- VGAscr *scr;
-
- scr = &vgascreen[0];
- if(scr->cur == nil || scr->cur->load == nil)
- return;
-
- scr->cur->load(scr, curs);
-}
-
-static ulong
-pixelbits(Memimage *i, Point pt)
-{
- uchar *p;
- ulong val;
- int off, bpp, npack;
-
- val = 0;
- p = byteaddr(i, pt);
- switch(bpp=i->depth){
- case 1:
- case 2:
- case 4:
- npack = 8/bpp;
- off = pt.x%npack;
- val = p[0] >> bpp*(npack-1-off);
- val &= (1<<bpp)-1;
- break;
- case 8:
- val = p[0];
- break;
- case 16:
- val = p[0]|(p[1]<<8);
- break;
- case 24:
- val = p[0]|(p[1]<<8)|(p[2]<<16);
- break;
- case 32:
- val = p[0]|(p[1]<<8)|(p[2]<<16)|(p[3]<<24);
- break;
- }
- while(bpp<32){
- val |= val<<bpp;
- bpp *= 2;
- }
- return val;
-}
-
-
-static ulong
-imgtorgba(Memimage *img, ulong val)
-{
- uchar r, g, b, a;
- int nb, ov, v;
- ulong chan;
- uchar *p;
-
- a = 0xFF;
- r = g = b = 0xAA; /* garbage */
- for(chan=img->chan; chan; chan>>=8){
- nb = NBITS(chan);
- ov = v = val&((1<<nb)-1);
- val >>= nb;
-
- while(nb < 8){
- v |= v<<nb;
- nb *= 2;
- }
- v >>= (nb-8);
-
- switch(TYPE(chan)){
- case CRed:
- r = v;
- break;
- case CGreen:
- g = v;
- break;
- case CBlue:
- b = v;
- break;
- case CAlpha:
- a = v;
- break;
- case CGrey:
- r = g = b = v;
- break;
- case CMap:
- p = img->cmap->cmap2rgb+3*ov;
- r = *p++;
- g = *p++;
- b = *p;
- break;
- }
- }
- return (r<<24)|(g<<16)|(b<<8)|a;
-}
-
-static ulong
-rgbatoimg(Memimage *img, ulong rgba)
-{
- ulong chan;
- int d, nb;
- ulong v;
- uchar *p, r, g, b, a, m;
-
- v = 0;
- r = rgba>>24;
- g = rgba>>16;
- b = rgba>>8;
- a = rgba;
- d = 0;
- for(chan=img->chan; chan; chan>>=8){
- nb = NBITS(chan);
- switch(TYPE(chan)){
- case CRed:
- v |= (r>>(8-nb))<<d;
- break;
- case CGreen:
- v |= (g>>(8-nb))<<d;
- break;
- case CBlue:
- v |= (b>>(8-nb))<<d;
- break;
- case CAlpha:
- v |= (a>>(8-nb))<<d;
- break;
- case CMap:
- p = img->cmap->rgb2cmap;
- m = p[(r>>4)*256+(g>>4)*16+(b>>4)];
- v |= m<<d;
- break;
- case CGrey:
- m = RGB2K(r,g,b);
- v |= m<<d;
- break;
- }
- d += nb;
- }
-// print("rgba2img %.8lux = %.*lux\n", rgba, 2*d/8, v);
- return v;
-}
-
-Memimage *lastbadi;
-Memdata *lastbad;
-Memimage *lastbadsrc, *lastbaddst;
-int hwaccel = 1;
-int hwblank = 1;
-
-int
-hwdraw(Memdrawparam *par)
-{
- int m;
- VGAscr *scr;
- Memimage *dst, *src;
-
- if(hwaccel == 0)
- return 0;
-
- dst = par->dst;
- scr = &vgascreen[0];
- if(dst == nil || dst->data == nil)
- return 0;
-
- if(dst->data->bdata != gscreendata.bdata)
- return 0;
-
-// if(dst->data != &gscreendata){
-// lastbad = dst->data;
-// lastbadi = dst;
-// return 0;
-// }
-
- if(scr->fill==nil && scr->scroll==nil)
- return 0;
-
- /*
- * If we have an opaque mask and source is one opaque
- * pixel we can convert to the destination format and just
- * replicate with memset.
- */
- m = Simplesrc|Simplemask|Fullmask;
- if(scr->fill && (par->state&m)==m && ((par->srgba&0xFF) == 0xFF))
- return scr->fill(scr, par->r, par->sdval);
-
- /*
- * If no source alpha, an opaque mask, we can just copy the
- * source onto the destination. If the channels are the same and
- * the source is not replicated, memmove suffices.
- */
- src = par->src;
- if(scr->scroll && src->data->bdata==dst->data->bdata && !(src->flags&Falpha)
- && (par->state&(Simplemask|Fullmask))==(Simplemask|Fullmask)){
-// if(src->zero != dst->zero){
-// lastbadsrc = src;
-// lastbaddst = dst;
-// iprint("#");
-// }
- return scr->scroll(scr, par->r, par->sr);
- }
-
- return 0;
-}
-
-void
-blankscreen(int blank)
-{
- VGAscr *scr;
-
- scr = &vgascreen[0];
- if(hwblank && scr->blank)
- scr->blank(scr, blank);
-}
+#include "../pc/screen.c"
M alphapc/screen.h => alphapc/screen.h +2 -0
@@ 47,6 47,8 @@ enum {
Pwhite = 0xFF,
};
+#define VGAMEM() PADDR(arch->pcimem(0xA0000, 1<<16))
+
#define vgai(port) inb(port)
#define vgao(port, data) outb(port, data)
M bitsy/screen.c => bitsy/screen.c +8 -8
@@ 393,12 393,12 @@ screenwin(void)
r = insetrect(gscreen->r, 4);
- memimagedraw(gscreen, r, memblack, ZP, memopaque, ZP);
+ memimagedraw(gscreen, r, memblack, ZP, memopaque, ZP, S);
window = insetrect(r, 4);
- memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP);
+ memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
memimagedraw(gscreen, Rect(window.min.x, window.min.y,
- window.max.x, window.min.y+h+5+6), orange, ZP, nil, ZP);
+ window.max.x, window.min.y+h+5+6), orange, ZP, nil, ZP, S);
freememimage(orange);
window = insetrect(window, 5);
@@ 445,7 445,7 @@ screenputc(char *buf)
pos = 4-(pos%4);
*xp++ = curpos.x;
r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
- memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min);
+ memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
flushmemscreen(r);
curpos.x += pos*w;
break;
@@ 454,7 454,7 @@ screenputc(char *buf)
break;
xp--;
r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
- memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min);
+ memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
flushmemscreen(r);
curpos.x = *xp;
break;
@@ 469,7 469,7 @@ screenputc(char *buf)
*xp++ = curpos.x;
r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h);
- memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min);
+ memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
flushmemscreen(r);
curpos.x += w;
@@ 486,10 486,10 @@ scroll(void)
o = 8*h;
r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
p = Pt(window.min.x, window.min.y+o);
- memimagedraw(gscreen, r, gscreen, p, nil, p);
+ memimagedraw(gscreen, r, gscreen, p, nil, p, S);
flushmemscreen(r);
r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
- memimagedraw(gscreen, r, back, ZP, nil, ZP);
+ memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
flushmemscreen(r);
curpos.y -= o;
M pc/devvga.c => pc/devvga.c +1 -1
@@ 322,7 322,7 @@ vgactl(Cmdbuf *cb)
return;
case CMdrawinit:
- memimagedraw(scr->gscreen, scr->gscreen->r, memblack, ZP, nil, ZP);
+ memimagedraw(scr->gscreen, scr->gscreen->r, memblack, ZP, nil, ZP, S);
if(scr && scr->dev && scr->dev->drawinit)
scr->dev->drawinit(scr);
return;
M pc/screen.c => pc/screen.c +11 -6
@@ 58,7 58,7 @@ screensize(int x, int y, int z, ulong chan)
error("screensize: vga soft memory");
/* memset(gscreendata.bdata, 0x72, width*BY2WD*y); /* not really black */
scr->useflush = 1;
- scr->aperture = 0xA0000;
+ scr->aperture = VGAMEM();
scr->apsize = 1<<16;
}
else
@@ 362,7 362,10 @@ hwdraw(Memdrawparam *par)
* replicate with memset.
*/
m = Simplesrc|Simplemask|Fullmask;
- if(scr->fill && (par->state&m)==m && ((par->srgba&0xFF) == 0xFF))
+ if(scr->fill
+ && (par->state&m)==m
+ && ((par->srgba&0xFF) == 0xFF)
+ && (par->op&S) == S)
return scr->fill(scr, par->r, par->sdval);
/*
@@ 370,11 373,14 @@ hwdraw(Memdrawparam *par)
* source onto the destination. If the channels are the same and
* the source is not replicated, memmove suffices.
*/
+ m = Simplemask|Fullmask;
src = par->src;
- if(scr->scroll && src->data->bdata==dst->data->bdata && !(src->flags&Falpha)
- && (par->state&(Simplemask|Fullmask))==(Simplemask|Fullmask)){
+ if(scr->scroll
+ && src->data->bdata==dst->data->bdata
+ && !(src->flags&Falpha)
+ && (par->state&m)==m
+ && (par->op&S) == S)
return scr->scroll(scr, par->r, par->sr);
- }
return 0;
}
@@ 385,7 391,6 @@ blankscreen(int blank)
VGAscr *scr;
scr = &vgascreen[0];
- scr->isblank = blank;
if(hwblank){
if(scr->blank)
scr->blank(scr, blank);
M pc/screen.h => pc/screen.h +1 -0
@@ 47,6 47,7 @@ enum {
Pwhite = 0xFF,
};
+#define VGAMEM() 0xA0000
#define vgai(port) inb(port)
#define vgao(port, data) outb(port, data)
M pc/vga.c => pc/vga.c +6 -6
@@ 54,9 54,9 @@ vgascroll(VGAscr* scr)
o = 8*h;
r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
p = Pt(window.min.x, window.min.y+o);
- memimagedraw(scr->gscreen, r, scr->gscreen, p, nil, p);
+ memimagedraw(scr->gscreen, r, scr->gscreen, p, nil, p, S);
r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
- memimagedraw(scr->gscreen, r, back, ZP, nil, ZP);
+ memimagedraw(scr->gscreen, r, back, ZP, nil, ZP, S);
curpos.y -= o;
}
@@ 99,7 99,7 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
pos = 4-(pos%4);
*xp++ = curpos.x;
r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
- memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min);
+ memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
curpos.x += pos*w;
break;
@@ 108,7 108,7 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
break;
xp--;
r = Rect(*xp, curpos.y, curpos.x, curpos.y+h);
- memimagedraw(scr->gscreen, r, back, back->r.min, nil, ZP);
+ memimagedraw(scr->gscreen, r, back, back->r.min, nil, ZP, S);
combinerect(flushr, r);
curpos.x = *xp;
break;
@@ 125,7 125,7 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
*xp++ = curpos.x;
r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y+h);
- memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min);
+ memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
memimagestring(scr->gscreen, curpos, conscol, ZP, scr->memdefont, buf);
combinerect(flushr, r);
curpos.x += w;
@@ 248,7 248,7 @@ cornerstring(char *s)
h = scr->memdefont->height;
r = Rect(0, 0, w, h);
- memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min);
+ memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
memimagestring(scr->gscreen, r.min, conscol, ZP, scr->memdefont, s);
// flushmemscreen(r);
}
M port/devdraw.c => port/devdraw.c +55 -22
@@ 80,6 80,7 @@ struct Client
int slot;
int refreshme;
int infoid;
+ int op;
};
struct Refresh
@@ 750,10 751,21 @@ drawnewclient(void)
memset(cl, 0, sizeof(Client));
cl->slot = i;
cl->clientid = ++sdraw.clientid;
+ cl->op = SoverD;
sdraw.client[i] = cl;
return cl;
}
+static int
+drawclientop(Client *cl)
+{
+ int op;
+
+ op = cl->op;
+ cl->op = SoverD;
+ return op;
+}
+
int
drawhasclients(void)
{
@@ 820,7 832,7 @@ drawpoint(Point *p, uchar *a)
}
Point
-drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int index)
+drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int index, int op)
{
FChar *fc;
Rectangle r;
@@ 833,7 845,7 @@ drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int ind
r.max.y = r.min.y+(fc->maxy-fc->miny);
sp1.x = sp->x+fc->left;
sp1.y = sp->y+fc->miny;
- memdraw(dst, r, src, sp1, font->image, Pt(fc->minx, fc->miny));
+ memdraw(dst, r, src, sp1, font->image, Pt(fc->minx, fc->miny), op);
p.x += fc->width;
sp->x += fc->width;
return p;
@@ 877,7 889,7 @@ deletescreenimage(void)
qunlock(&sdraw);
}
-Chan*
+static Chan*
drawattach(char *spec)
{
qlock(&sdraw);
@@ 889,7 901,7 @@ drawattach(char *spec)
return devattach('i', spec);
}
-Walkqid*
+static Walkqid*
drawwalk(Chan *c, Chan *nc, char **name, int nname)
{
if(screendata.bdata == nil)
@@ 1272,7 1284,7 @@ printmesg(char *fmt, uchar *a, int plsprnt)
void
drawmesg(Client *client, void *av, int n)
{
- int c, repl, m, y, dstid, scrnid, ni, ci, j, nw, e0, e1, ox, oy, esize, doflush;
+ int c, repl, m, y, dstid, scrnid, ni, ci, j, nw, e0, e1, op, ox, oy, oesize, esize, doflush;
uchar *u, *a, refresh;
char *fmt;
ulong value, chan;
@@ 1427,7 1439,8 @@ drawmesg(Client *client, void *av, int n)
drawrectangle(&r, a+13);
drawpoint(&p, a+29);
drawpoint(&q, a+37);
- memdraw(dst, r, src, p, mask, q);
+ op = drawclientop(client);
+ memdraw(dst, r, src, p, mask, q, op);
dstflush(dstid, dst, r);
continue;
@@ 1464,13 1477,14 @@ drawmesg(Client *client, void *av, int n)
c = -1;
ox = BGLONG(a+37);
oy = BGLONG(a+41);
+ op = drawclientop(client);
/* high bit indicates arc angles are present */
if(ox & (1<<31)){
if((ox & (1<<30)) == 0)
ox &= ~(1<<31);
- memarc(dst, p, e0, e1, c, src, sp, ox, oy);
+ memarc(dst, p, e0, e1, c, src, sp, ox, oy, op);
}else
- memellipse(dst, p, e0, e1, c, src, sp);
+ memellipse(dst, p, e0, e1, c, src, sp, op);
dstflush(dstid, dst, Rect(p.x-e0-j, p.y-e1-j, p.x+e0+j+1, p.y+e1+j+1));
continue;
@@ 1539,7 1553,7 @@ drawmesg(Client *client, void *av, int n)
error(Eindex);
drawrectangle(&r, a+11);
drawpoint(&p, a+27);
- memdraw(font->image, r, src, p, memopaque, p);
+ memdraw(font->image, r, src, p, memopaque, p, S);
fc = &font->fchar[ci];
fc->minx = r.min.x;
fc->maxx = r.max.x;
@@ 1566,7 1580,8 @@ drawmesg(Client *client, void *av, int n)
error("negative line width");
src = drawimage(client, a+33);
drawpoint(&sp, a+37);
- memline(dst, p, q, e0, e1, j, src, sp);
+ op = drawclientop(client);
+ memline(dst, p, q, e0, e1, j, src, sp, op);
/* avoid memlinebbox if possible */
if(dstid==0 || dst->layer!=nil){
/* BUG: this is terribly inefficient: update maximal containing rect*/
@@ 1672,6 1687,15 @@ drawmesg(Client *client, void *av, int n)
}
continue;
+ /* set compositing operator for next draw operation: 'O' op */
+ case 'O':
+ printmesg(fmt="b", a, 0);
+ m = 1+1;
+ if(n < m)
+ error(Eshortdraw);
+ client->op = a[1];
+ continue;
+
/* filled polygon: 'P' dstid[4] n[2] wind[4] ignore[2*4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
/* polygon: 'p' dstid[4] n[2] end0[4] end1[4] radius[4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
case 'p':
@@ 1704,8 1728,11 @@ drawmesg(Client *client, void *av, int n)
if(dstid==0 || (dst->layer && dst->layer->screen->image->data == screenimage->data))
doflush = 1; /* simplify test in loop */
ox = oy = 0;
+ esize = 0;
u = a+m;
for(y=0; y<ni; y++){
+ q = p;
+ oesize = esize;
u = drawcoord(u, a+n, ox, &p.x);
u = drawcoord(u, a+n, oy, &p.y);
ox = p.x;
@@ 1726,16 1753,22 @@ drawmesg(Client *client, void *av, int n)
}
if(*a=='P' && e0!=1 && e0 !=~0)
r = dst->clipr;
- else
- r = Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1);
- dstflush(dstid, dst, r);
+ else if(y > 0){
+ r = Rect(q.x-oesize, q.y-oesize, q.x+oesize+1, q.y+oesize+1);
+ combinerect(&r, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));
+ }
+ if(rectclip(&r, dst->clipr)) /* should perhaps be an arg to dstflush */
+ dstflush(dstid, dst, r);
}
pp[y] = p;
}
+ if(y == 1)
+ dstflush(dstid, dst, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));
+ op = drawclientop(client);
if(*a == 'p')
- mempoly(dst, pp, ni, e0, e1, j, src, sp);
+ mempoly(dst, pp, ni, e0, e1, j, src, sp, op);
else
- memfillpoly(dst, pp, ni, e0, src, sp);
+ memfillpoly(dst, pp, ni, e0, src, sp, op);
free(pp);
m = u-a;
continue;
@@ 1793,6 1826,7 @@ drawmesg(Client *client, void *av, int n)
error(Eshortdraw);
clipr = dst->clipr;
dst->clipr = r;
+ op = drawclientop(client);
if(*a == 'x'){
/* paint background */
l = drawimage(client, a+47);
@@ 1811,7 1845,7 @@ drawmesg(Client *client, void *av, int n)
r.max.x += font->fchar[ci].width;
u += 2;
}
- memdraw(dst, r, l, q, memopaque, ZP);
+ memdraw(dst, r, l, q, memopaque, ZP, op);
u -= 2*ni;
}
q = p;
@@ 1821,7 1855,7 @@ drawmesg(Client *client, void *av, int n)
dst->clipr = clipr;
error(Eindex);
}
- q = drawchar(dst, q, src, &sp, font, ci);
+ q = drawchar(dst, q, src, &sp, font, ci, op);
u += 2;
}
dst->clipr = clipr;
@@ 2020,17 2054,16 @@ drawactive(int active)
{
if(active){
drawblankscreen(0);
- sdraw.blanktime = 0;
+ sdraw.blanktime = MACHP(0)->ticks;
}else{
- if(blanktime && TK2SEC(sdraw.blanktime)/60 >= blanktime)
+ if(blanktime && sdraw.blanktime && TK2SEC(MACHP(0)->ticks - sdraw.blanktime)/60 >= blanktime)
drawblankscreen(1);
- else
- sdraw.blanktime++;
}
}
int
drawidletime(void)
{
- return TK2SEC(sdraw.blanktime)/60;
+ return TK2SEC(MACHP(0)->ticks - sdraw.blanktime)/60;
}
+