/*
* rhdr has a write message to the bitblt file.
* It may hold any number of bitblt protocol requests,
* but only the last, at most, should call for a reply.
* Format the requests to the out file.
* Set thdr.count to amount consumed.
* Return 0 if ok, else an error message
*/
char *
bitwrite(void)
{
long n, m;
uchar *p;
n = rhdr.count;
p = (uchar *)rhdr.data;
if(detail)
Bprint(out, "*** Request length %d\n", rhdr.count);
while(n > 0) {
rtype = *p;
m = req(p, n);
if(m == 0)
exits("bad request format");
if(write(bitfd, p, m) != m) {
errstr(errbuf);
Bprint(out, "error writing /dev/bitblt: %s\n", errbuf);
return errbuf;
}
n -= m;
p += m;
}
thdr.count = rhdr.count - n;
Bflush(out);
return 0;
}
/*
* rhdr has a read message to the bitblt file.
* Read from the real bitblt fd,
* format the reply to the out file.
* Set thdr.data to point at the reply,
* and thdr.count to amount returned.
* Return 0 if ok, else an error message
*/
char *
bitread(void)
{
long n;
/* Format one request, return number of bytes consumed */
int
req(uchar *p, int m)
{
int len;
int v, i;
ulong ws, l;
long miny, maxy, t;
Bitmap *bm;
Point pt;
case 't':
len = 23;
Bprint(out, "[t] texture, dst=%d, rect=%R, src=%d, code=%A\n",
BGSHORT(p+1), bgrect(p+3), BGSHORT(p+19), BGSHORT(p+21));
break;
case 'v':
len = 7;
Bprint(out, "[v] font cache clear, font=%d, ncache=%d, width=%d\n",
BGSHORT(p+1), BGSHORT(p+3), BGSHORT(p+5));
break;
case 'w':
v = BGSHORT(p+1);
bm = bmlook(v);
miny = BGLONG(p+3);
maxy = BGLONG(p+7);
ws = 1<<(3-bm->ldepth); /* pixels per byte */
/* set l to number of bytes of incoming data per scan line */
if(bm->r.min.x >= 0)
l = (bm->r.max.x+ws-1)/ws - bm->r.min.x/ws;
else{ /* make positive before divide */
t = (-bm->r.min.x)+ws-1;
t = (t/ws)*ws;
l = (t+bm->r.max.x+ws-1)/ws;
}
len = 11 + l*(maxy-miny);
Bprint(out, "[w] bitmap write, bitmap=%d, miny=%d, maxy=%d\n",
v, miny, maxy);
dumpbmrows(p+11, l, bm->ldepth,
Rect(bm->r.min.x, miny, bm->r.max.x, maxy));
break;
case 'x':
len = 9;
Bprint(out, "[x] cursorset, pt=%P\n", bgpt(p+1));
break;
case 'y':
len = 9;
Bprint(out, "[y] load font char, font=%d, cache index=%d, subfont=%d, subfont index=%d\n",
BGSHORT(p+1), BGSHORT(p+3), BGSHORT(p+5), BGSHORT(p+7));
break;
case 'z':
v = BGSHORT(p+1);
bm = bmlook(v);
l = 1 << (1 << bm->ldepth);
len = 3 + 12*l;
Bprint(out, "[z] colormap write, bitmap=%d\n", v);
printcmap(p+3, l);
break;
}
if(m < len) {
Bprint(out, "\tEbadblt: request length %d, should be %d\n", m, len);
len = 0;
}
return len;
}
void
rep(uchar *p, int n)
{
int len, v;
Bitmap *bm;
long t;
ulong l, ws;
len = -n;
switch(rtype) {
case 'i':
len = 34;
if(p[0] != 'I') {
Bprint(out, "Expected reply 'I', got '%c'\n", p[0]);
break;
}
bm = bmlook(0);
bm->ldepth = p[1];
bm->r = bgrect(p+2);
Bprint(out, "[I] ldepth=%d, rect=%R, clip rect=%R\n",
p[1], bm->r, bgrect(p+18));
if(n >= 34 + 3*12) {
v = atoi((char *)(p+34));
Bprint(out, "\tdefont, n=%d, height=%d, ascent=%d\n",
v, atoi((char *)(p+34+12)), atoi((char *)(p+34+24)));
printfontchars(p+34+3*12, v);
len = 34+3*12+6*(v+1);
}
break;
case 'a':
len = 3;
if(p[0] != 'A') {
Bprint(out, "Expected reply 'A', got '%c'\n", p[0]);
break;
}
v = BGSHORT(p+1);
Bprint(out, "[A] bitmap=%d\n", v);
bm = bmlook(v);
bm->r = rrect;
bm->ldepth = rldepth;
break;
case 'k':
len = 3;
if(p[0] != 'K') {
Bprint(out, "Expected reply 'K', got '%c'\n", p[0]);
break;
}
Bprint(out, "[K] subfont=%d\n", BGSHORT(p+1));
break;
case 'j':
if(p[0] != 'J') {
Bprint(out, "Expected reply 'J', got '%c'\n", p[0]);
break;
}
v = atoi((char *)(p+3));
Bprint(out, "[J] subfont=%d, n=%d, height=%d, ascent=%d\n",
BGSHORT(p+1), v, atoi((char *)(p+3+12)),
atoi((char *)(p+3+24)));
printfontchars(p+3+3*12, v);
len = 3+3*12+6*(v+1);
break;
case 'n':
len = 3;
if(p[0] != 'N') {
Bprint(out, "Expected reply 'N', got '%c'\n", p[0]);
break;
}
Bprint(out, "[N] font=%d\n", BGSHORT(p+1));
break;
case 'm':
bm = bmlook(rid);
v = 1 << (1 << bm->ldepth);
len = 12*v;
printcmap(p, v);
break;
case 'r':
bm = bmlook(rid);
ws = 1<<(3-bm->ldepth); /* pixels per byte */
/* set l to number of bytes of incoming data per scan line */
if(bm->r.min.x >= 0)
l = (bm->r.max.x+ws-1)/ws - bm->r.min.x/ws;
else{ /* make positive before divide */
t = (-bm->r.min.x)+ws-1;
t = (t/ws)*ws;
l = (t+bm->r.max.x+ws-1)/ws;
}
dumpbmrows(p, l, bm->ldepth,
Rect(bm->r.min.x, rminy, bm->r.max.x, rmaxy));
len = l*(rmaxy-rminy);
break;
}
if(n != len)
Bprint(out, "\tBad reply length %d, should be %d\n", n, len);
}