From 8a94bf7ba9da5a1e8afd44fea13ef363469fc383 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 5 Dec 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-12-05 --- alphapc/screen.c | 533 +---------------------------------------------- alphapc/screen.h | 2 + bitsy/screen.c | 16 +- pc/devvga.c | 2 +- pc/screen.c | 17 +- pc/screen.h | 1 + pc/vga.c | 12 +- port/devdraw.c | 77 +++++-- 8 files changed, 85 insertions(+), 575 deletions(-) diff --git a/alphapc/screen.c b/alphapc/screen.c index a4ffb07f3c7bfe1495d181940db454a291053fd3..9497add993cd40828391c42bd0637fc3c9164030 100644 --- a/alphapc/screen.c +++ b/alphapc/screen.c @@ -1,532 +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 -#include -#include -#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<chan; chan; chan>>=8){ - nb = NBITS(chan); - ov = v = val&((1<>= nb; - - while(nb < 8){ - v |= 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))<>(8-nb))<>(8-nb))<>(8-nb))<cmap->rgb2cmap; - m = p[(r>>4)*256+(g>>4)*16+(b>>4)]; - v |= m<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" diff --git a/alphapc/screen.h b/alphapc/screen.h index 38148570b3f58baf88f437539572e5a0e1bd5f71..e92a04e04fc7796cc275c38907b14f93cc153416 100644 --- a/alphapc/screen.h +++ b/alphapc/screen.h @@ -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) diff --git a/bitsy/screen.c b/bitsy/screen.c index 25244aa85956aef05efd2be61295fc4eca0efefb..29b1b0c8ba2a75cfb6f4638ecd587a21686bb045 100644 --- a/bitsy/screen.c +++ b/bitsy/screen.c @@ -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; diff --git a/pc/devvga.c b/pc/devvga.c index 7ebeebd2675e83eab1eaa3ac8dbbbada0de73a44..0af18e9e575e1ae451a3875050f0997df6f870d2 100644 --- a/pc/devvga.c +++ b/pc/devvga.c @@ -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; diff --git a/pc/screen.c b/pc/screen.c index 7a784bbee483c076d26b51ce2bd8ebf44180deb1..6eb63d07393883ed8898ecb5f226f73aead5e888 100644 --- a/pc/screen.c +++ b/pc/screen.c @@ -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); diff --git a/pc/screen.h b/pc/screen.h index 3d94c1846a2541ff55ec877c9f2cf8299d2e41d2..3e9a57771fcc3c96f424f70663bd12b467e72566 100644 --- a/pc/screen.h +++ b/pc/screen.h @@ -47,6 +47,7 @@ enum { Pwhite = 0xFF, }; +#define VGAMEM() 0xA0000 #define vgai(port) inb(port) #define vgao(port, data) outb(port, data) diff --git a/pc/vga.c b/pc/vga.c index 9694acf6d5211faf99eb5f0641c719d98ae78d8b..14f6b6be7e2ec74306f7eeda84ac19cd0a3150ac 100644 --- a/pc/vga.c +++ b/pc/vga.c @@ -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); } diff --git a/port/devdraw.c b/port/devdraw.c index 0f0f6d4699871eedba430dc5102a46d4640f11bc..3619d5a0101d61e5bb7bda21233475ed1e034c3a 100644 --- a/port/devdraw.c +++ b/port/devdraw.c @@ -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; yclipr; - 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; } +