Yaroslav Kolomiietsfew renames52ec96d7 years agoHistory
209 lines · 4.2 KB · C
RawDownload
#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	padresize(Rdp*); static	void	drawupd1(Rdp*,Imgupd*); extern	/* load.c */	int	loadbmp(Image*,Rectangle,uchar*,int,uchar*);	int	loadrle(Image*,Rectangle,uchar*,int,uchar*); static intdepth2chan(int depth){	int chan; 	switch(depth){	default:	sysfatal("Unsupported remote color depth: %uhd\n", depth);	case 8:	chan = CMAP8; break;	case 15:	chan = RGB15; break;	case 16:	chan = RGB16; break;	case 24:	chan = RGB24; break;	case 32:	chan = XRGB32; break;	}	return chan;} voidinitscreen(Rdp* c){	if(initdraw(drawerror, nil, c->label) < 0)		sysfatal("initdraw: %r");	display->locking = 1;	unlockdisplay(display);	c->ysz = Dy(screen->r);	c->xsz = (Dx(screen->r) +3) & ~3;} voiddrawimgupdate(Rdp *c, Share* s){	int (*getupd)(Imgupd*, uchar*, uint);	uchar* p, *ep;	int n, nr;	Imgupd u;		switch(s->type){	default:	sysfatal("drawimgupdate: bad s->type");	case ShUimg:	getupd = getimgupd; break;	case ShUorders:	getupd = getfupd; break;	} 	p = s->data;	ep = s->data + s->ndata;	nr = s->nr; 	if(display->locking)		lockdisplay(display);	while(p<ep && nr>0){		if((n = getupd(&u, p, ep-p)) < 0)			sysfatal("getimgupd: %r");		drawupd1(c, &u);		p += n;		nr--;	}	flushimage(display, 1);	if(display->locking)		unlockdisplay(display);} static voidpadresize(Rdp* c){	Rectangle rs;	int chan; 	rs = rectaddpt(Rpt(ZP, Pt(c->xsz+4, c->ysz+4)), screen->r.min);	if(pad==nil || eqrect(pad->r, rs) == 0){		chan = depth2chan(c->depth);		freeimage(pad);		pad = allocimage(display, rs, chan, 0, DNofill);		if(pad==nil)			sysfatal("drawimgupdate: %r");	}} static voidimgupd(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->compressed)		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);} static voidscrblt(Rdp* c, Imgupd* up){	Rectangle r;	Point p; 	USED(c);	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 voidmemblt(Rdp* c, Imgupd* up){	Image* img;	Rectangle clipr, r;	Point pt; 	USED(c);	if(up->cid >= nelem(icache) || up->coff >= nelem(*icache)){		fprint(2, "drawmemimg: bad cache spec [%d %d]\n", up->cid, up->coff);		return;	}	img = icache[up->cid][up->coff];	if(img == nil){		fprint(2, "drawmemimg: empty cache entry cid %d coff %d\n", up->cid, up->coff);		return;	} 	if(up->clip){		clipr = Rect(up->cx, up->cy, up->cx+up->cxsz, up->cy+up->cysz);		replclipr(screen, screen->repl, rectaddpt(clipr, screen->r.min));	} 	r = Rect(up->x, up->y, up->xm+1, up->ym+1);	r = rectaddpt(r, screen->r.min);	pt = Pt(up->sx, up->sy);	draw(screen, r, img, nil, pt); 	if(up->clip)		replclipr(screen, screen->repl, screen->r);} static voidcacheimg(Rdp* c, Imgupd* u){	int (*loadfn)(Image*,Rectangle,uchar*,int,uchar*);	int chan;	Image* img;	Rectangle r; 	loadfn = loadbmp;	if(u->compressed)		loadfn = loadrle; 	r = Rect(0, 0, u->xsz, u->ysz); 	if(u->cid >= nelem(icache) || u->coff >= nelem(*icache))		sysfatal("cacheimg: bad cache spec [%d %d]", u->cid, u->coff); 	img = icache[u->cid][u->coff];	if(img==nil || eqrect(img->r, r)==0){		chan = depth2chan(c->depth);		freeimage(img);		img = allocimage(display, r, chan, 0, DNofill);		if(img == nil)			sysfatal("cacheimg: %r");		icache[u->cid][u->coff] = img;	} 	if(loadfn(img, r, u->bytes, u->nbytes, c->cmap) < 0)		sysfatal("loadmemimg: %r");} static voidcachecmap(Rdp* c, Imgupd* up){	/* BUG: who cares? */	USED(c);	USED(up);} static voiddrawupd1(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 Ucacheimg:	cacheimg(c, up); break;	case Umcache:	cachecmap(c, up); break;	}}