shithub: rd

Download patch

ref: dc727820e82824593280146a7ff353ea1da05e11
parent: 55f6ab5055793d69cd0ae8c0bbd3a952ef1fd505
author: Yaroslav Kolomiiets <yarikos@gmail.com>
date: Mon Aug 8 14:51:44 EDT 2016

add drawmemimg+loadmeming

--- a/dat.h
+++ b/dat.h
@@ -239,10 +239,18 @@
 	int	ysz;
 	int	depth;
 	int	iscompr;
+	int	cid;
+	int	coff;
+	int	sx;
+	int	sy;
 	int	nbytes;
 	uchar*	bytes;
 };
 int	getimgupd(Imgupd*, uchar*, uint);
+uchar*	getmemblt(Imgupd*, uchar*, uchar*, int, int);
+int	getimgcache2(Imgupd*, uchar*, uint, int, int);
+void	loadmemimg(Rdp*, Imgupd*);
+void	drawmemimg(Rdp*, Imgupd*);
 
 
 enum 
--- a/draw.c
+++ b/draw.c
@@ -1,3 +1,7 @@
+/*
+ * depending on CanMemBlt servers will only do
+ * either loadmeming+drawmemimg or drawimgupdate.
+ */
 #include <u.h>
 #include <libc.h>
 #include <draw.h>
@@ -4,6 +8,8 @@
 #include "dat.h"
 #include "fns.h"
 
+static Image*	imgcache[3][600];
+
 /* 2.2.9.1.1.3.1.2.1 Bitmap Update Data (TS_UPDATE_BITMAP_DATA) */
 void
 drawimgupdate(Rdp *c, Share* s)
@@ -22,7 +28,7 @@
 
 	if(display->locking)
 		lockdisplay(display);
-	if(pad==nil || eqrect(pad->r, screen->r) != 0){
+	if(pad==nil || eqrect(pad->r, screen->r) == 0){
 		freeimage(pad);
 		pad = allocimage(display, screen->r, c->chan, 0, DNofill);
 		if(pad==nil)
@@ -63,4 +69,58 @@
 		draw(d->screenimage, r, d->screenimage, nil, sr.min);
 	if(d && d->locking)
 		unlockdisplay(d);
+}
+
+void
+loadmemimg(Rdp* c, Imgupd* iu)
+{
+	int (*loadfn)(Image*,Rectangle,uchar*,int,uchar*);
+	Image* img;
+	Rectangle r;
+
+	loadfn = loadbmp;
+	if(iu->iscompr)
+		loadfn = loadrle;
+
+	r = Rect(0, 0, iu->xsz, iu->ysz);
+
+	if(iu->cid >= nelem(imgcache) || iu->coff >= nelem(*imgcache))
+		sysfatal("cacheimage2: bad cache spec [%d %d]", iu->cid, iu->coff);
+
+	img = imgcache[iu->cid][iu->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");
+		imgcache[iu->cid][iu->coff] = img;
+	}
+
+	if(loadfn(img, r, iu->bytes, iu->nbytes, c->cmap) < 0)
+		sysfatal("%r");
+}
+
+void
+drawmemimg(Rdp*, Imgupd* iu)
+{
+	Image* img;
+	Rectangle r;
+	Point pt;
+
+	/* called with display locked */
+
+	if(iu->cid >= nelem(imgcache) || iu->coff >= nelem(*imgcache)){
+		fprint(2, "drawmemimg: bad cache spec [%d %d]\n", iu->cid, iu->coff);
+		return;
+	}
+	img = imgcache[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);
+	pt = Pt(iu->sx, iu->sy);
+	draw(screen, rectaddpt(r, screen->r.min), img, nil, pt);
+
 }
--- a/egdi.c
+++ b/egdi.c
@@ -91,22 +91,16 @@
 static	uchar*	scrblt(Rdp*, uchar*,uchar*,int,int);
 static	uchar*	memblt(Rdp*, uchar*,uchar*,int,int);
 static	uchar*	cacheimage2(Rdp*, uchar*,uchar*,int,int);
-static	uchar*	cacheimage(Rdp*, uchar*,uchar*,int,int);
 static	uchar*	cachecmap(Rdp*, uchar*,uchar*,int,int);
 
 Order ordtab[NumOrders] = {
 	[ScrBlt]= 		{ 1, scrblt },
 	[MemBlt]=	{ 2, memblt },
-	[PatBlt]= 		{ 2, nil },
-	[OpaqueRect]=	{ 1, nil },
-	[MultiOpaqueRect]=	{ 2, nil },
 };
 
 Order auxtab[8] = {
 	[CacheImage2]=		{ 0, cacheimage2 },
 	[CacheCompressed2]= 	{ 0, cacheimage2 },
-	[CacheImage]=			{ 0, cacheimage },
-	[CacheCompressed]= 	{ 0, cacheimage },
 	[CacheCmap]=			{ 0, cachecmap },
 };
 
@@ -115,8 +109,6 @@
 {
 	[CanScrBlt]   	1,
 	[CanMemBlt]	1,
-//	[CanMultiOpaqueRect] 1,
-//	[CanPatBlt]   	1,	/* and OpaqueRect */
 };
 
 static struct GdiContext
@@ -125,8 +117,6 @@
 	Rectangle clipr;
 } gc	= {PatBlt};
 
-static Image*	imgcache[3][600];
-
 static	uchar*	getclipr(Rectangle*,uchar*,uchar*);
 static	uchar*	getpt(Point*,uchar*,uchar*,int,int);
 
@@ -136,7 +126,7 @@
 {
 	int count;
 	uchar *p, *ep;
-	int ctl, fmask, fsize;
+	int ctl, fset, fsize;
 	int size, opt, xorder;
 
 	count = as->nord;
@@ -144,7 +134,7 @@
 	ep = as->data + as->ndata;
 
 	while(count-- > 0 && p<ep){	
-		fmask = 0;
+		fset = 0;
 		ctl = *p;
 		if(!(ctl&Standard))
 			goto ErrNstd;	// GDI+ or out of sync
@@ -177,13 +167,13 @@
 		default:
 			goto ErrFsize;
 		case 3:
-			fmask = p[0]|(p[1]<<8)|(p[2]<<16);
+			fset = p[0]|(p[1]<<8)|(p[2]<<16);
 			break;
 		case 2:
-			fmask = GSHORT(p);
+			fset = GSHORT(p);
 			break;
 		case 1:
-			fmask = p[0];
+			fset = p[0];
 		case 0:
 			break;
 		}
@@ -194,7 +184,7 @@
 
 		if(ordtab[gc.order].fn == nil)
 			goto ErrNotsup;
-		p = ordtab[gc.order].fn(c, p, ep, ctl, fmask);
+		p = ordtab[gc.order].fn(c, p, ep, ctl, fset);
 		if(p == nil)
 			break;
 	}
@@ -252,22 +242,22 @@
 }
 
 static uchar*
-getpt(Point* pp, uchar* s, uchar *es,  int ctl, int fmask)
+getpt(Point* pp, uchar* s, uchar *es,  int ctl, int fset)
 {
 	Point p;
 
 	p = *pp;
 	if(ctl&Diff){
-		if(fmask&1<<0)
+		if(fset&1<<0)
 			p.x += (char)*s++;
-		if(fmask&1<<1)
+		if(fset&1<<1)
 			p.y += (char)*s++;
 	}else{
-		if(fmask&1<<0){
+		if(fset&1<<0){
 			p.x = GSHORT(s);
 			s += 2;
 		};
-		if(fmask&1<<1){
+		if(fset&1<<1){
 			p.y = GSHORT(s);
 			s += 2;
 		};
@@ -279,13 +269,13 @@
 }
 
 static uchar*
-getoffrect(Rectangle* pr, uchar* p, uchar* ep, int ctl, int fmask){
+getoffrect(Rectangle* pr, uchar* p, uchar* ep, int ctl, int fset){
 	Rectangle r;
 
 	r = *pr;
 	r.max = subpt(r.max, r.min);
-	p = getpt(&r.min, p, ep, ctl, fmask);
-	p = getpt(&r.max, p, ep, ctl, fmask>>2);
+	p = getpt(&r.min, p, ep, ctl, fset);
+	p = getpt(&r.max, p, ep, ctl, fset>>2);
 	r.max = addpt(r.max, r.min);
 	*pr = r;
 	return p;
@@ -293,7 +283,7 @@
 
 /* 2.2.2.2.1.1.2.7 ScrBlt (SCRBLT_ORDER) */
 static uchar*
-scrblt(Rdp*, uchar* p, uchar* ep, int ctl, int fmask)
+scrblt(Rdp*, uchar* p, uchar* ep, int ctl, int fset)
 {
 	static	Rectangle wr;
 	static	Point wp;
@@ -300,10 +290,10 @@
 	static	int rop3;
 	Rectangle r, sr;
 
-	p = getoffrect(&wr, p, ep, ctl, fmask);
-	if(fmask&1<<4)
+	p = getoffrect(&wr, p, ep, ctl, fset);
+	if(fset&1<<4)
 		rop3 = *p++;
-	p = getpt(&wp, p, ep, ctl, fmask>>5);
+	p = getpt(&wp, p, ep, ctl, fset>>5);
 	if(ctl&Clipped)
 		rectclip(&wr, gc.clipr);
 
@@ -318,9 +308,8 @@
 	return p;
 }
 
-/* 2.2.2.2.1.1.2.9 MemBlt (MEMBLT_ORDER) */
-static uchar*
-memblt(Rdp*, uchar* p, uchar* ep, int ctl, int fmask)
+uchar*
+getmemblt(Imgupd* iu, uchar* p, uchar* ep, int ctl, int fset)
 {
 	static int cid;	/* cacheId */
 	static int coff;	/* cacheIndex */
@@ -327,39 +316,50 @@
 	static int rop3;
 	static Rectangle r;
 	static Point pt;
-	Image* img;
 
-	if(fmask&1<<0){
+	if(fset&1<<0){
 		cid = GSHORT(p);
 		p += 2;
 	}
-	p = getoffrect(&r, p, ep, ctl, fmask>>1);
-	if(fmask&1<<5)
+	p = getoffrect(&r, p, ep, ctl, fset>>1);
+	if(fset&1<<5)
 		rop3 = *p++;
-	p = getpt(&pt, p, ep, ctl, fmask>>6);
-	if(fmask&1<<8){
+	p = getpt(&pt, p, ep, ctl, fset>>6);
+	if(fset&1<<8){
 		coff = GSHORT(p);
 		p += 2;
 	}
 	if(p>ep)
-		sysfatal("memblt: %s", Eshort);
+		sysfatal("getmemblt: %s", Eshort);
 
 	cid &= Bits8;
-	if(cid >= nelem(imgcache) || coff >= nelem(*imgcache)){
-		fprint(2, "memblt: bad image cache spec [%d %d]\n", cid, coff);
-		return p;
-	}
-	img = imgcache[cid][coff];
-	if(img == nil){
-		fprint(2, "memblt: empty cache entry cid %d coff %d\n", cid, coff);
-		return p;
-	}
 
+	iu->cid = cid;
+	iu->coff = coff;
+	iu->x = r.min.x;
+	iu->y = r.min.y;
+	iu->xm = r.max.x-1;
+	iu->ym = r.max.y-1;
+	iu->xsz = Dx(r);
+	iu->ysz = Dy(r);
+	iu->sx = pt.x;
+	iu->sy = pt.y;
+	return p;
+}
+
+/* 2.2.2.2.1.1.2.9 MemBlt (MEMBLT_ORDER) */
+static uchar*
+memblt(Rdp* c, uchar* p, uchar* ep, int ctl, int fset)
+{
+	Imgupd u;
+
+	p = getmemblt(&u, p, ep, ctl, fset);
+
 	if(display->locking)
 		lockdisplay(display);
 	if(ctl&Clipped)
 		replclipr(screen, screen->repl, rectaddpt(gc.clipr, screen->r.min));
-	draw(screen, rectaddpt(r, screen->r.min), img, nil, pt);
+	drawmemimg(c, &u);
 	if(ctl&Clipped)
 		replclipr(screen, screen->repl, screen->r);
 	if(display->locking)
@@ -368,109 +368,41 @@
 	return p;
 }
 
-static Image*
-pickimage(int cid, int coff, Rectangle r, ulong chan)
+int
+getimgcache2(Imgupd* iu, uchar* a, uint nb, int xorder, int opt)
 {
-	Image* img;
-
-	if(cid >= nelem(imgcache) || coff >= nelem(*imgcache)){
-		werrstr("bad image cache spec [%d %d]", cid, coff);
-		return nil;
-	}
-
-	img = imgcache[cid][coff];
-	if(img==nil || !eqrect(img->r, r)){
-		if(img != nil)
-			freeimage(img);
-		img = allocimage(display, r, chan, 0, DNofill);
-		if(img == nil)
-			return nil;
-		imgcache[cid][coff] = img;
-	}
-	return img;
-}
-
-/* 2.2.2.2.1.2.2 Cache Bitmap - Revision 1 (CACHE_BITMAP_ORDER) */
-static uchar*
-cacheimage(Rdp* c, uchar* p, uchar* ep, int xorder, int opt)
-{
+	uchar *p, *ep;
 	int cid;	/* cacheId */
 	int coff;	/* cacheIndex */
-	int chan;
-	int zip;
-	int err;
+	int n, g;
 	int size;
-	Image* img;
-	Point d;	/* width, height */
-	Rectangle r;
 
-	if(p+15 >= ep)
-		sysfatal("cacheimage: %s", Eshort);
-	cid = p[6];
-	d.x = p[8];
-	d.y = p[9];
-	size = GSHORT(p+11);
-	coff = GSHORT(p+13);
-	r.min = ZP;
-	r.max = d;
-	chan = c->chan;
-	zip = (xorder==CacheCompressed);
+	p = a;
+	ep = a+nb;
 
-	if(zip)
-	if(opt&1<<10){
-		p += 8;	// bitmapComprHdr
-		size -= 8;
-	}
-	if(p+size > ep)
-		sysfatal("cacheimage: size: %s", Eshort);
-	if((img = pickimage(cid, coff, r, chan)) == nil)
-		sysfatal("cacheimage: pickimage: %r");
-	err = (zip? loadrle : loadbmp)(img, r, p, size, c->cmap);
-	if(err < 0)
-		sysfatal("%r");
-	return p+size;
-}
+	iu->iscompr = (xorder==CacheCompressed2);
 
-/* 2.2.2.2.1.2.3 Cache Bitmap - Revision 2 (CACHE_BITMAP_REV2_ORDER) */
-static uchar*
-cacheimage2(Rdp* c, uchar* p,uchar* ep, int xorder, int opt)
-{
-	int n, g;
-	int zip;
-	int cid;	/* cacheId */
-	int coff;	/* cacheIndex */
-	int chan;
-	int size;
-	int err;
-	Image* img;
-	Point d;
-	Rectangle r;
+	cid = opt&Bits3;
+	opt >>= 7;
 
 	if(p+9 >= ep)
 		sysfatal("cacheimage2: %s", Eshort);
-	p += 6;
 
-	chan = c->chan;
-	zip = (xorder==CacheCompressed2);
-	cid = opt&Bits3;
-	opt >>= 7;
-
+	p += 6;
 	if(opt&1<<1)
 		p += 8;	// persistent cache key
 	g = *p++;
 	if(g&1<<7)
 		g = ((g&Bits7)<<8) | *p++;
-	d.x = g;
+	iu->xsz = g;
 	if(opt&1)
-		d.y = d.x;
+		iu->ysz = g;
 	else{
 		g = *p++;
 		if(g&1<<7)
 			g = ((g&Bits7)<<8) | *p++;
-		d.y = g;
+		iu->ysz = g;
 	}
-	r.min = ZP;
-	r.max = d;
 
 	g = *p++;
 	n = g>>6;
@@ -488,17 +420,33 @@
 		g = ((g&Bits7)<<8) | *p++;
 	coff = g;
 
-	if(zip&& !(opt&1<<3)){
+
+	if(iu->iscompr && !(opt&1<<3)){
 		p += 8;	// bitmapComprHdr
 		size -= 8;
 	}
 	if(p+size > ep)
 		sysfatal("cacheimage2: size: %s", Eshort);
-	if((img = pickimage(cid, coff, r, chan)) == nil)
-		sysfatal("cacheimage2: pickimage: %r");
-	err = (zip? loadrle : loadbmp)(img, r, p, size, c->cmap);
-	if(err < 0)
-		sysfatal("%r");
+	iu->cid = cid;
+	iu->coff = coff;
+	iu->nbytes = size;
+	iu->bytes = p;
+
+	return size;
+}
+
+/* 2.2.2.2.1.2.3 Cache Bitmap - Revision 2 (CACHE_BITMAP_REV2_ORDER) */
+static uchar*
+cacheimage2(Rdp* c, uchar* p, uchar* ep, int xorder, int opt)
+{
+	int size;
+	Imgupd iupd, *iu;
+
+	iu = &iupd;
+
+	size = getimgcache2(iu, p, ep-p, xorder, opt);
+	loadmemimg(c, iu);
+
 	return p+size;
 }