ref: 1025d6ab452ace62b65cf4a07f8bb2d8a46bc9fb
dir: /draw.c/
#include <u.h> #include <libc.h> #include <draw.h> #include "dat.h" #include "fns.h" static Image* pad; static Image* icache[3][600]; static void drawupd(Rdp*,Imgupd*); static void padresize(Rdp*); /* 2.2.9.1.1.3.1.2.1 Bitmap Update Data (TS_UPDATE_BITMAP_DATA) */ void drawimgupdate(Rdp *c, Share* s) { uchar* p, *ep; int n, nr; Imgupd u; assert(s->type == ShUimg); p = s->data; ep = s->data + s->ndata; nr = s->nr; if(display->locking) lockdisplay(display); while(p<ep && nr>0){ if((n = getimgupd(&u, p, ep-p)) < 0) sysfatal("getimgupd: %r"); drawupd(c, &u); p += n; nr--; } flushimage(display, 1); if(display->locking) unlockdisplay(display); } /* 2.2.2.2 Fast-Path Orders Update (TS_FP_UPDATE_ORDERS) */ void draworders(Rdp* c, Share* as) { int n, count; uchar *p, *ep; Imgupd u; count = as->nr; p = as->data; ep = as->data + as->ndata; if(display->locking) lockdisplay(display); while(count> 0 && p<ep){ n = getfupd(&u, p, ep-p); drawupd(c, &u); p += n; count--; } flushimage(display, 1); if(display->locking) unlockdisplay(display); } static void padresize(Rdp* c) { Rectangle rs; rs = rectaddpt(Rpt(ZP, Pt(c->xsz+4, c->ysz+4)), screen->r.min); if(pad==nil || eqrect(pad->r, rs) == 0){ freeimage(pad); pad = allocimage(display, rs, c->chan, 0, DNofill); if(pad==nil) sysfatal("drawimgupdate: %r"); } } static void imgupd(Rdp* c, Imgupd* up) { Rectangle r; int (*loadfn)(Image*,Rectangle,uchar*,int,uchar*); padresize(c); // BUG call elsewhere - whenever c->xsz changes if(up->depth != pad->depth) sysfatal("bad image depth"); loadfn = loadbmp; if(up->iscompr) loadfn = loadrle; r = rectaddpt(Rect(up->x, up->y, up->x+up->xsz, up->y+up->ysz), screen->r.min); if(loadfn(pad, r, up->bytes, up->nbytes, c->cmap) < 0) sysfatal("drawimgupdate: %r"); r = rectaddpt(Rect(up->x, up->y, up->xm+1, up->ym+1), screen->r.min); draw(screen, r, pad, nil, r.min); } void drawmemimg(Rdp*, Imgupd* iu) { Image* img; Rectangle r; Point pt; /* called with display locked */ if(iu->cid >= nelem(icache) || iu->coff >= nelem(*icache)){ fprint(2, "drawmemimg: bad cache spec [%d %d]\n", iu->cid, iu->coff); return; } img = icache[iu->cid][iu->coff]; if(img == nil){ fprint(2, "drawmemimg: empty cache entry cid %d coff %d\n", iu->cid, iu->coff); return; } r = Rect(iu->x, iu->y, iu->xm+1, iu->ym+1); r = rectaddpt(r, screen->r.min); pt = Pt(iu->sx, iu->sy); draw(screen, r, img, nil, pt); } static void scrblt(Rdp*, Imgupd* up) { Rectangle r; Point p; r = rectaddpt(Rect(up->x, up->y, up->x+up->xsz, up->y+up->ysz), screen->r.min); p = addpt(Pt(up->sx, up->sy), screen->r.min); draw(screen, r, screen, nil, p); } static void memblt(Rdp* c, Imgupd* up) { if(up->clipped) replclipr(screen, screen->repl, rectaddpt(up->clipr, screen->r.min)); drawmemimg(c, up); if(up->clipped) replclipr(screen, screen->repl, screen->r); } static void cacheimage2(Rdp* c, Imgupd* up) { int (*loadfn)(Image*,Rectangle,uchar*,int,uchar*); Image* img; Rectangle r; loadfn = loadbmp; if(up->iscompr) loadfn = loadrle; r = Rect(0, 0, up->xsz, up->ysz); if(up->cid >= nelem(icache) || up->coff >= nelem(*icache)) sysfatal("cacheimage2: bad cache spec [%d %d]", up->cid, up->coff); img = icache[up->cid][up->coff]; if(img==nil || eqrect(img->r, r)==0){ freeimage(img); img = allocimage(display, r, c->chan, 0, DNofill); if(img == nil) sysfatal("cacheimage2: %r"); icache[up->cid][up->coff] = img; } if(loadfn(img, r, up->bytes, up->nbytes, c->cmap) < 0) sysfatal("loadmemimg: %r"); } static void cachecmap(Rdp*, Imgupd*) { /* BUG: who cares? */ } static void drawupd(Rdp* c, Imgupd* up) { switch(up->type){ case Ubitmap: imgupd(c, up); break; case Uscrblt: scrblt(c, up); break; case Umemblt: memblt(c, up); break; case Uicache: cacheimage2(c, up); break; case Umcache: cachecmap(c, up); break; } }