shithub: rd

Download patch

ref: 3caa4956a884576789997ebdd1cd47c70f0cbfcb
parent: 3a9bd2b51c2c1627c4dabac83f83af3a5c0b86be
author: Yaroslav Kolomiiets <yarikos@gmail.com>
date: Tue Aug 9 10:30:46 EDT 2016

egdi.c: split parsing

--- a/dat.h
+++ b/dat.h
@@ -230,7 +230,17 @@
 void	loadcmap(Rdp*,Share*);
 void	scanorders(Rdp*,Share*);
 
-struct Imgupd {
+enum /* Imgupd.type */
+{
+	Ubitmap,
+	Uscrblt,
+	Umemblt,
+	Uicache,
+	Umcache,
+};
+struct Imgupd
+{
+	int	type;
 	int	x;
 	int	y;
 	int	xm;
@@ -243,12 +253,17 @@
 	int	coff;
 	int	sx;
 	int	sy;
+	int	clipped;
+	Rectangle	clipr;
 	int	nbytes;
 	uchar*	bytes;
 };
 int	getimgupd(Imgupd*, uchar*, uint);
-uchar*	getmemblt(Imgupd*, uchar*, uchar*, int, int);
-int	getimgcache2(Imgupd*, uchar*, uint, int, int);
+int	getscrblt(Imgupd*,uchar*,uint,int,int);
+int	getmemblt(Imgupd*,uchar*,uint,int,int);
+int	getimgcache2(Imgupd*,uchar*,uint,int,int);
+int	getcmapcache(Imgupd*,uchar*,uint,int,int);
+
 void	loadmemimg(Rdp*, Imgupd*);
 void	drawmemimg(Rdp*, Imgupd*);
 
--- a/egdi.c
+++ b/egdi.c
@@ -8,6 +8,8 @@
 #include "dat.h"
 #include "fns.h"
 
+#define	DBG	if(0)
+
 enum
 {
 	Bits2=	3,
@@ -32,7 +34,7 @@
 };
 enum
 {
-	ROP2_COPY	= 0xcc,
+	Scopy	= 0xcc,
 };
 enum
 {
@@ -85,23 +87,24 @@
 struct Order
 {
 	int	fsize;
-	uchar* (*fn)(Rdp*, uchar*,uchar*,int,int);
+	void (*fn)(Rdp*,Imgupd*);
+	int (*get)(Imgupd*,uchar*,uint,int,int);
 };
 
-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*	cachecmap(Rdp*, uchar*,uchar*,int,int);
+static	void	scrblt(Rdp*,Imgupd*);
+static	void	memblt(Rdp*,Imgupd*);
+static	void	cacheimage2(Rdp*,Imgupd*);
+static	void	cachecmap(Rdp*,Imgupd*);
 
 Order ordtab[NumOrders] = {
-	[ScrBlt]= 		{ 1, scrblt },
-	[MemBlt]=	{ 2, memblt },
+	[ScrBlt]= 		{ 1, scrblt,	getscrblt },
+	[MemBlt]=	{ 2, memblt,	getmemblt },
 };
 
 Order auxtab[8] = {
-	[CacheImage2]=		{ 0, cacheimage2 },
-	[CacheCompressed2]= 	{ 0, cacheimage2 },
-	[CacheCmap]=			{ 0, cachecmap },
+	[CacheImage2]=		{ 0, cacheimage2, getimgcache2  },
+	[CacheCompressed2]= 	{ 0, cacheimage2, getimgcache2 },
+	[CacheCmap]=			{ 0, cachecmap, getcmapcache },
 };
 
 uchar
@@ -117,8 +120,8 @@
 	Rectangle clipr;
 } gc	= {PatBlt};
 
-static	uchar*	getclipr(Rectangle*,uchar*,uchar*);
-static	uchar*	getpt(Point*,uchar*,uchar*,int,int);
+static	int	cfclipr(Rectangle*,uchar*,int);
+static	int	cfpt(Point*,uchar*,int,int,int);
 
 /* 2.2.2.2 Fast-Path Orders Update (TS_FP_UPDATE_ORDERS) */
 void
@@ -127,7 +130,8 @@
 	int count;
 	uchar *p, *ep;
 	int ctl, fset, fsize;
-	int size, opt, xorder;
+	int n, size, opt, xorder;
+	Imgupd u;
 
 	count = as->nord;
 	p = as->data;
@@ -137,7 +141,7 @@
 		fset = 0;
 		ctl = *p;
 		if(!(ctl&Standard))
-			goto ErrNstd;	// GDI+ or out of sync
+			goto ErrNstd;
 		if(ctl&Secondary){
 			if(p+6>ep)
 				sysfatal("scanorders: %s", Eshort);
@@ -146,13 +150,14 @@
 				sysfatal("scanorders: size: %s", Eshort);
 			opt = GSHORT(p+3);
 			xorder = p[5];
-			if(xorder >= nelem(auxtab) || auxtab[xorder].fn == nil){
+			if(xorder >= nelem(auxtab) || auxtab[xorder].get == nil){
 				fprint(2, "egdi: unsupported secondary order %d\n", xorder);
 				p += size;
 				continue;
 			}
 
-			auxtab[xorder].fn(c, p, p+size, xorder, opt);
+			auxtab[xorder].get(&u, p, size, xorder, opt);
+			auxtab[xorder].fn(c, &u);
 			p += size;
 			continue;
 		}
@@ -180,13 +185,13 @@
 		p += fsize;
 
 		if(ctl&Clipped && !(ctl&SameClipping))
-			p = getclipr(&gc.clipr, p, ep);
+			p += cfclipr(&gc.clipr, p, ep-p);
 
-		if(ordtab[gc.order].fn == nil)
+		if(ordtab[gc.order].get == nil)
 			goto ErrNotsup;
-		p = ordtab[gc.order].fn(c, p, ep, ctl, fset);
-		if(p == nil)
-			break;
+		n = ordtab[gc.order].get(&u, p, ep-p, ctl, fset);
+		ordtab[gc.order].fn(c, &u);
+		p += n;
 	}
 	if(display->locking)
 		lockdisplay(display);
@@ -196,7 +201,7 @@
 	return;
 
 ErrNstd:
-	fprint(2, "egdi: non-standard order\n");
+	fprint(2, "egdi: non-standard order (GDI+ or out of sync)\n");
 	return;
 ErrFsize:
 	fprint(2, "egdi: bad field encoding bytes count for order %d\n", gc.order);
@@ -206,11 +211,62 @@
 	return;
 }
 
-static uchar*
-getclipr(Rectangle* pr, uchar* p, uchar* ep)
+static int
+cfpt(Point* p, uchar* a, int nb, int isdelta, int fset)
 {
+	int n;
+
+	n = 0;
+	if(isdelta){
+		if(fset&1<<0)
+			n++;
+		if(fset&1<<1)
+			n++;
+	}else{
+		if(fset&1<<0)
+			n += 2;
+		if(fset&1<<1)
+			n += 2;
+	}
+	if(n>nb)
+		sysfatal("cfpt: %s", Eshort);
+
+	if(isdelta){
+		if(fset&1<<0)
+			p->x += (signed char)*a++;
+		if(fset&1<<1)
+			p->y += (signed char)*a;
+	}else{
+		if(fset&1<<0){
+			p->x = GSHORT(a);
+			a += 2;
+		};
+		if(fset&1<<1)
+			p->y = GSHORT(a);
+	}
+	return n;
+}
+
+static int
+cfrect(Rectangle* pr, uchar* p, int nb, int isdelta, int fset){
+	int n, m;
+
+	pr->max = subpt(pr->max, pr->min);
+	n = cfpt(&pr->min, p, nb, isdelta, fset);
+	m = cfpt(&pr->max, p+n, nb-n, isdelta, fset>>2);
+	pr->max = addpt(pr->max, pr->min);
+	return n+m;
+}
+
+static int
+cfclipr(Rectangle* pr, uchar* a, int nb)
+{
 	int bctl;
+	uchar *p, *ep;
 
+	p = a;
+	ep = a+nb;
+
 	bctl = *p++;
 	if(bctl&1<<4)
 		pr->min.x += (char)*p++;
@@ -237,79 +293,55 @@
 		p += 2;
 	}
 	if(p>ep)
-		sysfatal("getclipr: %s", Eshort);
-	return p;
+		sysfatal("cfclipr: %s", Eshort);
+	return p-a;
 }
 
-static uchar*
-getpt(Point* pp, uchar* s, uchar *es,  int ctl, int fset)
-{
-	Point p;
-
-	p = *pp;
-	if(ctl&Diff){
-		if(fset&1<<0)
-			p.x += (char)*s++;
-		if(fset&1<<1)
-			p.y += (char)*s++;
-	}else{
-		if(fset&1<<0){
-			p.x = GSHORT(s);
-			s += 2;
-		};
-		if(fset&1<<1){
-			p.y = GSHORT(s);
-			s += 2;
-		};
-	}
-	if(s > es)
-		sysfatal("getpt: %s", Eshort);
-	*pp = p;
-	return s;
-}
-
-static uchar*
-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, fset);
-	p = getpt(&r.max, p, ep, ctl, fset>>2);
-	r.max = addpt(r.max, r.min);
-	*pr = r;
-	return p;
-}
-
 /* 2.2.2.2.1.1.2.7 ScrBlt (SCRBLT_ORDER) */
-static uchar*
-scrblt(Rdp*, uchar* p, uchar* ep, int ctl, int fset)
+int
+getscrblt(Imgupd* up, uchar* a, uint nb, int ctl, int fset)
 {
+	int n;
+	uchar *p, *ep;
+	Rectangle r;
 	static	Rectangle wr;
 	static	Point wp;
 	static	int rop3;
-	Rectangle r, sr;
 
-	p = getoffrect(&wr, p, ep, ctl, fset);
-	if(fset&1<<4)
+DBG	fprint(2, "getscrblt...");
+	p = a;
+	ep = a+nb;
+
+	n = cfrect(&wr, p, ep-p, ctl&Diff, fset);
+	p += n;
+	if(fset&1<<4){
+		if(ep-p<1)
+			sysfatal(Eshort);
 		rop3 = *p++;
-	p = getpt(&wp, p, ep, ctl, fset>>5);
+	}
+	n = cfpt(&wp, p, ep-p, ctl&Diff, fset>>5);
+	p += n;
+
+	r = wr;
 	if(ctl&Clipped)
-		rectclip(&wr, gc.clipr);
+		rectclip(&r, gc.clipr);
 
-	if(rop3 != ROP2_COPY){
+	if(rop3 != Scopy)
 		fprint(2, "scrblt: rop3 %#hhux is not supported\n", rop3);
-		return p;
-	}
 
-	r = rectaddpt(wr, screen->r.min);
-	sr = rectaddpt(Rpt(wp, Pt(Dx(r), Dy(r))), screen->r.min);
-	scroll(display, r, sr);
-	return p;
+	up->type = Uscrblt;
+	up->x = r.min.x;
+	up->y = r.min.y;
+	up->xsz = Dx(r);
+	up->ysz = Dy(r);
+	up->sx = wp.x;
+	up->sy = wp.y;
+
+	return p-a;
 }
 
-uchar*
-getmemblt(Imgupd* iu, uchar* p, uchar* ep, int ctl, int fset)
+int
+getmemblt(Imgupd* up, uchar* a, uint nb, int ctl, int fset)
 {
 	static int cid;	/* cacheId */
 	static int coff;	/* cacheIndex */
@@ -316,15 +348,23 @@
 	static int rop3;
 	static Rectangle r;
 	static Point pt;
+	int n;
+	uchar *p, *ep;
+DBG	fprint(2, "getmemblt...");
 
+	p = a;
+	ep = a+nb;
+
 	if(fset&1<<0){
 		cid = GSHORT(p);
 		p += 2;
 	}
-	p = getoffrect(&r, p, ep, ctl, fset>>1);
+	n = cfrect(&r, p, ep-p, ctl&Diff, fset>>1);
+	p += n;
 	if(fset&1<<5)
 		rop3 = *p++;
-	p = getpt(&pt, p, ep, ctl, fset>>6);
+	n = cfpt(&pt, p, ep-p, ctl&Diff, fset>>6);
+	p += n;
 	if(fset&1<<8){
 		coff = GSHORT(p);
 		p += 2;
@@ -334,42 +374,29 @@
 
 	cid &= Bits8;
 
-	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;
-}
+	up->type = Umemblt;
+	up->cid = cid;
+	up->coff = coff;
+	up->x = r.min.x;
+	up->y = r.min.y;
+	up->xm = r.max.x-1;
+	up->ym = r.max.y-1;
+	up->xsz = Dx(r);
+	up->ysz = Dy(r);
+	up->sx = pt.x;
+	up->sy = pt.y;
+	up->clipped = 0;
+	if(ctl&Clipped){
+		up->clipped = 1;
+		up->clipr = gc.clipr;
+	}
 
-/* 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));
-	drawmemimg(c, &u);
-	if(ctl&Clipped)
-		replclipr(screen, screen->repl, screen->r);
-	if(display->locking)
-		unlockdisplay(display);
-
-	return p;
+	return p-a;
 }
 
+/* 2.2.2.2.1.2.3 Cache Bitmap - Revision 2 (CACHE_BITMAP_REV2_ORDER) */
 int
-getimgcache2(Imgupd* iu, uchar* a, uint nb, int xorder, int opt)
+getimgcache2(Imgupd* up, uchar* a, uint nb, int xorder, int opt)
 {
 	uchar *p, *ep;
 	int cid;	/* cacheId */
@@ -377,10 +404,11 @@
 	int n, g;
 	int size;
 
+DBG	fprint(2, "getimgcache2...");
 	p = a;
 	ep = a+nb;
 
-	iu->iscompr = (xorder==CacheCompressed2);
+	up->iscompr = (xorder==CacheCompressed2);
 
 	cid = opt&Bits3;
 	opt >>= 7;
@@ -394,14 +422,14 @@
 	g = *p++;
 	if(g&1<<7)
 		g = ((g&Bits7)<<8) | *p++;
-	iu->xsz = g;
+	up->xsz = g;
 	if(opt&1)
-		iu->ysz = g;
+		up->ysz = g;
 	else{
 		g = *p++;
 		if(g&1<<7)
 			g = ((g&Bits7)<<8) | *p++;
-		iu->ysz = g;
+		up->ysz = g;
 	}
 
 	g = *p++;
@@ -420,53 +448,81 @@
 		g = ((g&Bits7)<<8) | *p++;
 	coff = g;
 
-
-	if(iu->iscompr && !(opt&1<<3)){
+	if(up->iscompr && !(opt&1<<3)){
 		p += 8;	// bitmapComprHdr
 		size -= 8;
 	}
 	if(p+size > ep)
 		sysfatal("cacheimage2: size: %s", Eshort);
-	iu->cid = cid;
-	iu->coff = coff;
-	iu->nbytes = size;
-	iu->bytes = p;
 
+	up->type = Uicache;
+	up->cid = cid;
+	up->coff = coff;
+	up->nbytes = size;
+	up->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)
+/* 2.2.2.2.1.2.4 Cache Color Table (CACHE_COLOR_TABLE_ORDER) */
+int
+getcmapcache(Imgupd* up, uchar* a, uint nb, int, int)
 {
-	int size;
-	Imgupd iupd, *iu;
+	int cid, n;
+DBG	fprint(2, "getcmapcache...");
+	
+	cid = a[6];
+	n = GSHORT(a+7);
+	if(n != 256)
+		sysfatal("cachecmap: %d != 256", n);
+	if(9+4*256 > nb)
+		sysfatal(Eshort);
+	up->type = Umcache;
+	up->cid = cid;
+	up->bytes = a+9;
+	up->nbytes = 4*256;
+	return 9+4*256;
+}
 
-	iu = &iupd;
 
-	size = getimgcache2(iu, p, ep-p, xorder, opt);
-	loadmemimg(c, iu);
 
-	return p+size;
+static void
+scrblt(Rdp*, Imgupd* up)
+{
+	Rectangle r, sr;
+
+DBG	fprint(2, "scrblt...");
+	r = rectaddpt(Rect(up->x, up->y, up->x+up->xsz, up->y+up->ysz), screen->r.min);
+	sr = rectaddpt(Rpt(Pt(up->sx, up->sy), Pt(Dx(r), Dy(r))), screen->r.min);
+	scroll(display, r, sr);
 }
 
-/* 2.2.2.2.1.2.4 Cache Color Table (CACHE_COLOR_TABLE_ORDER) */
-static uchar*
-cachecmap(Rdp*, uchar* p,uchar* ep, int, int)
+static void
+memblt(Rdp* c, Imgupd* up)
 {
-	int cid, n;
-	
-	cid = p[6];
-	n = GSHORT(p+7);
-	if(n != 256){
-		fprint(2, "cachecmap: %d != 256\n", n);
-		return nil;
-	}
-	if(p+9+4*256>ep){
-		werrstr(Eshort);
-		return nil;
-	}
-	/* fixed cmap here */
-	USED(cid);
-	return p+9+4*256;
+DBG	fprint(2, "memblt...");
+	if(display->locking)
+		lockdisplay(display);
+	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);
+	if(display->locking)
+		unlockdisplay(display);
+}
+
+
+static void
+cacheimage2(Rdp* c, Imgupd* up)
+{
+DBG	fprint(2, "cacheimage2...");
+	loadmemimg(c, up);
+}
+
+
+static void
+cachecmap(Rdp*, Imgupd*)
+{
+DBG	fprint(2, "cachecmap...");
+	/* BUG: who cares? */
 }
--- a/mpas.c
+++ b/mpas.c
@@ -316,6 +316,7 @@
 		werrstr(Eshort);
 		return -1;
 	}
+	iu->type = Ubitmap;
 	iu->x = GSHORT(p+0);
 	iu->y = GSHORT(p+2);
 	iu->xm = GSHORT(p+4);