xref: /inferno-os/libdraw/unloadimage.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth #include "lib9.h"
2*37da2899SCharles.Forsyth #include "draw.h"
3*37da2899SCharles.Forsyth #include "kernel.h"
4*37da2899SCharles.Forsyth #include "interp.h"
5*37da2899SCharles.Forsyth 
6*37da2899SCharles.Forsyth int
unloadimage(Image * i,Rectangle r,uchar * data,int ndata)7*37da2899SCharles.Forsyth unloadimage(Image *i, Rectangle r, uchar *data, int ndata)
8*37da2899SCharles.Forsyth {
9*37da2899SCharles.Forsyth 	int bpl, n, ntot, dy;
10*37da2899SCharles.Forsyth 	uchar *a;
11*37da2899SCharles.Forsyth 	Display *d;
12*37da2899SCharles.Forsyth 
13*37da2899SCharles.Forsyth 	if(!rectinrect(r, i->r)){
14*37da2899SCharles.Forsyth 		kwerrstr("unloadimage: bad rectangle");
15*37da2899SCharles.Forsyth 		return -1;
16*37da2899SCharles.Forsyth 	}
17*37da2899SCharles.Forsyth 	bpl = bytesperline(r, i->depth);
18*37da2899SCharles.Forsyth 	if(ndata < bpl*Dy(r)){
19*37da2899SCharles.Forsyth 		kwerrstr("unloadimage: buffer too small");
20*37da2899SCharles.Forsyth 		return -1;
21*37da2899SCharles.Forsyth 	}
22*37da2899SCharles.Forsyth 
23*37da2899SCharles.Forsyth 	d = i->display;
24*37da2899SCharles.Forsyth 	flushimage(d, 0);	/* make sure subsequent flush is for us only */
25*37da2899SCharles.Forsyth 	ntot = 0;
26*37da2899SCharles.Forsyth 	while(r.min.y < r.max.y){
27*37da2899SCharles.Forsyth 		a = bufimage(d, 1+4+4*4);
28*37da2899SCharles.Forsyth 		if(a == 0){
29*37da2899SCharles.Forsyth 			kwerrstr("unloadimage: %r");
30*37da2899SCharles.Forsyth 			return -1;
31*37da2899SCharles.Forsyth 		}
32*37da2899SCharles.Forsyth 		dy = 8000/bpl;
33*37da2899SCharles.Forsyth 		if(dy <= 0){
34*37da2899SCharles.Forsyth 			kwerrstr("unloadimage: image too wide");
35*37da2899SCharles.Forsyth 			return -1;
36*37da2899SCharles.Forsyth 		}
37*37da2899SCharles.Forsyth 		if(dy > Dy(r))
38*37da2899SCharles.Forsyth 			dy = Dy(r);
39*37da2899SCharles.Forsyth 		a[0] = 'r';
40*37da2899SCharles.Forsyth 		BPLONG(a+1, i->id);
41*37da2899SCharles.Forsyth 		BPLONG(a+5, r.min.x);
42*37da2899SCharles.Forsyth 		BPLONG(a+9, r.min.y);
43*37da2899SCharles.Forsyth 		BPLONG(a+13, r.max.x);
44*37da2899SCharles.Forsyth 		BPLONG(a+17, r.min.y+dy);
45*37da2899SCharles.Forsyth 		if(flushimage(d, 0) < 0)
46*37da2899SCharles.Forsyth 			return -1;
47*37da2899SCharles.Forsyth 		if(d->local == 0)
48*37da2899SCharles.Forsyth 			release();
49*37da2899SCharles.Forsyth 		n = kchanio(d->datachan, data+ntot, ndata-ntot, OREAD);
50*37da2899SCharles.Forsyth 		if(d->local == 0)
51*37da2899SCharles.Forsyth 			acquire();
52*37da2899SCharles.Forsyth 		if(n < 0)
53*37da2899SCharles.Forsyth 			return n;
54*37da2899SCharles.Forsyth 		ntot += n;
55*37da2899SCharles.Forsyth 		r.min.y += dy;
56*37da2899SCharles.Forsyth 	}
57*37da2899SCharles.Forsyth 	return ntot;
58*37da2899SCharles.Forsyth }
59