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;
}