#include <u.h>#include <libc.h>#include <draw.h> Image*allocimage(Display *d, Rectangle r, u32int chan, int repl, u32int val){ Image* i; i = _allocimage(nil, d, r, chan, repl, val, 0, 0); if (i) setmalloctag(i, getcallerpc(&d)); return i;} Image*_allocimage(Image *ai, Display *d, Rectangle r, u32int chan, int repl, u32int val, int screenid, int refresh){ uchar *a; char *err; Image *i; Rectangle clipr; int id; int depth; err = 0; i = 0; if(chan == 0){ werrstr("bad channel descriptor"); return nil; } depth = chantodepth(chan); if(depth == 0){ err = "bad channel descriptor"; Error: if(err) werrstr("allocimage: %s", err); else werrstr("allocimage: %r"); free(i); return 0; } /* flush pending data so we don't get error allocating the image */ flushimage(d, 0); a = bufimage(d, 1+4+4+1+4+1+4*4+4*4+4); if(a == 0) goto Error; d->imageid++; id = d->imageid; a[0] = 'b'; BPLONG(a+1, id); BPLONG(a+5, screenid); a[9] = refresh; BPLONG(a+10, chan); a[14] = repl; BPLONG(a+15, r.min.x); BPLONG(a+19, r.min.y); BPLONG(a+23, r.max.x); BPLONG(a+27, r.max.y); if(repl) /* huge but not infinite, so various offsets will leave it huge, not overflow */ clipr = Rect(-0x3FFFFFFF, -0x3FFFFFFF, 0x3FFFFFFF, 0x3FFFFFFF); else clipr = r; BPLONG(a+31, clipr.min.x); BPLONG(a+35, clipr.min.y); BPLONG(a+39, clipr.max.x); BPLONG(a+43, clipr.max.y); BPLONG(a+47, val); if(flushimage(d, 0) < 0) goto Error; if(ai) i = ai; else{ i = malloc(sizeof(Image)); if(i == nil){ a = bufimage(d, 1+4); if(a){ a[0] = 'f'; BPLONG(a+1, id); flushimage(d, 0); } goto Error; } } i->display = d; i->id = id; i->depth = depth; i->chan = chan; i->r = r; i->clipr = clipr; i->repl = repl; i->screen = 0; i->next = 0; return i;} Image*namedimage(Display *d, char *name){ uchar *a; char *err, buf[12*12+1]; Image *i; int id, n; u32int chan; err = 0; i = 0; n = strlen(name); if(n >= 256){ err = "name too long"; Error: if(err) werrstr("namedimage: %s", err); else werrstr("namedimage: %r"); if(i) free(i); return 0; } /* flush pending data so we don't get error allocating the image */ flushimage(d, 0); a = bufimage(d, 1+4+1+n); if(a == 0) goto Error; d->imageid++; id = d->imageid; a[0] = 'n'; BPLONG(a+1, id); a[5] = n; memmove(a+6, name, n); if(flushimage(d, 0) < 0) goto Error; if(pread(d->ctlfd, buf, sizeof buf, 0) < 12*12) goto Error; buf[12*12] = '\0'; i = malloc(sizeof(Image)); if(i == nil){ Error1: a = bufimage(d, 1+4); if(a){ a[0] = 'f'; BPLONG(a+1, id); flushimage(d, 0); } goto Error; } i->display = d; i->id = id; if((chan=strtochan(buf+2*12))==0){ werrstr("bad channel '%.12s' from devdraw", buf+2*12); goto Error1; } i->chan = chan; i->depth = chantodepth(chan); i->repl = atoi(buf+3*12); i->r.min.x = atoi(buf+4*12); i->r.min.y = atoi(buf+5*12); i->r.max.x = atoi(buf+6*12); i->r.max.y = atoi(buf+7*12); i->clipr.min.x = atoi(buf+8*12); i->clipr.min.y = atoi(buf+9*12); i->clipr.max.x = atoi(buf+10*12); i->clipr.max.y = atoi(buf+11*12); i->screen = 0; i->next = 0; return i;} intnameimage(Image *i, char *name, int in){ uchar *a; int n; n = strlen(name); a = bufimage(i->display, 1+4+1+1+n); if(a == 0) return 0; a[0] = 'N'; BPLONG(a+1, i->id); a[5] = in; a[6] = n; memmove(a+7, name, n); if(flushimage(i->display, 0) < 0) return 0; return 1;} int_freeimage1(Image *i){ uchar *a; Display *d; Image *w; if(i == 0 || i->display == 0) return 0; /* make sure no refresh events occur on this if we block in the write */ d = i->display; /* flush pending data so we don't get error deleting the image */ flushimage(d, 0); a = bufimage(d, 1+4); if(a == 0) return -1; a[0] = 'f'; BPLONG(a+1, i->id); if(i->screen){ w = d->windows; if(w == i) d->windows = i->next; else while(w){ if(w->next == i){ w->next = i->next; break; } w = w->next; } } if(flushimage(d, i->screen!=0) < 0) return -1; return 0;} intfreeimage(Image *i){ int ret; ret = _freeimage1(i); free(i); return ret;}
#include <u.h>
#include <libc.h>
#include <draw.h>
Image*
allocimage(Display *d, Rectangle r, u32int chan, int repl, u32int val)
{
Image* i;
i = _allocimage(nil, d, r, chan, repl, val, 0, 0);
if (i)
setmalloctag(i, getcallerpc(&d));
return i;
}
Image*
_allocimage(Image *ai, Display *d, Rectangle r, u32int chan, int repl, u32int val, int screenid, int refresh)
{
uchar *a;
char *err;
Image *i;
Rectangle clipr;
int id;
int depth;
err = 0;
i = 0;
if(chan == 0){
werrstr("bad channel descriptor");
return nil;
}
depth = chantodepth(chan);
if(depth == 0){
err = "bad channel descriptor";
Error:
if(err)
werrstr("allocimage: %s", err);
else
werrstr("allocimage: %r");
free(i);
return 0;
}
/* flush pending data so we don't get error allocating the image */
flushimage(d, 0);
a = bufimage(d, 1+4+4+1+4+1+4*4+4*4+4);
if(a == 0)
goto Error;
d->imageid++;
id = d->imageid;
a[0] = 'b';
BPLONG(a+1, id);
BPLONG(a+5, screenid);
a[9] = refresh;
BPLONG(a+10, chan);
a[14] = repl;
BPLONG(a+15, r.min.x);
BPLONG(a+19, r.min.y);
BPLONG(a+23, r.max.x);
BPLONG(a+27, r.max.y);
if(repl)
/* huge but not infinite, so various offsets will leave it huge, not overflow */
clipr = Rect(-0x3FFFFFFF, -0x3FFFFFFF, 0x3FFFFFFF, 0x3FFFFFFF);
else
clipr = r;
BPLONG(a+31, clipr.min.x);
BPLONG(a+35, clipr.min.y);
BPLONG(a+39, clipr.max.x);
BPLONG(a+43, clipr.max.y);
BPLONG(a+47, val);
if(flushimage(d, 0) < 0)
goto Error;
if(ai)
i = ai;
else{
i = malloc(sizeof(Image));
if(i == nil){
a = bufimage(d, 1+4);
if(a){
a[0] = 'f';
BPLONG(a+1, id);
flushimage(d, 0);
}
goto Error;
}
}
i->display = d;
i->id = id;
i->depth = depth;
i->chan = chan;
i->r = r;
i->clipr = clipr;
i->repl = repl;
i->screen = 0;
i->next = 0;
return i;
}
Image*
namedimage(Display *d, char *name)
{
uchar *a;
char *err, buf[12*12+1];
Image *i;
int id, n;
u32int chan;
err = 0;
i = 0;
n = strlen(name);
if(n >= 256){
err = "name too long";
Error:
if(err)
werrstr("namedimage: %s", err);
else
werrstr("namedimage: %r");
if(i)
free(i);
return 0;
}
/* flush pending data so we don't get error allocating the image */
flushimage(d, 0);
a = bufimage(d, 1+4+1+n);
if(a == 0)
goto Error;
d->imageid++;
id = d->imageid;
a[0] = 'n';
BPLONG(a+1, id);
a[5] = n;
memmove(a+6, name, n);
if(flushimage(d, 0) < 0)
goto Error;
if(pread(d->ctlfd, buf, sizeof buf, 0) < 12*12)
goto Error;
buf[12*12] = '\0';
i = malloc(sizeof(Image));
if(i == nil){
Error1:
a = bufimage(d, 1+4);
if(a){
a[0] = 'f';
BPLONG(a+1, id);
flushimage(d, 0);
}
goto Error;
}
i->display = d;
i->id = id;
if((chan=strtochan(buf+2*12))==0){
werrstr("bad channel '%.12s' from devdraw", buf+2*12);
goto Error1;
}
i->chan = chan;
i->depth = chantodepth(chan);
i->repl = atoi(buf+3*12);
i->r.min.x = atoi(buf+4*12);
i->r.min.y = atoi(buf+5*12);
i->r.max.x = atoi(buf+6*12);
i->r.max.y = atoi(buf+7*12);
i->clipr.min.x = atoi(buf+8*12);
i->clipr.min.y = atoi(buf+9*12);
i->clipr.max.x = atoi(buf+10*12);
i->clipr.max.y = atoi(buf+11*12);
i->screen = 0;
i->next = 0;
return i;
}
int
nameimage(Image *i, char *name, int in)
{
uchar *a;
int n;
n = strlen(name);
a = bufimage(i->display, 1+4+1+1+n);
if(a == 0)
return 0;
a[0] = 'N';
BPLONG(a+1, i->id);
a[5] = in;
a[6] = n;
memmove(a+7, name, n);
if(flushimage(i->display, 0) < 0)
return 0;
return 1;
}
int
_freeimage1(Image *i)
{
uchar *a;
Display *d;
Image *w;
if(i == 0 || i->display == 0)
return 0;
/* make sure no refresh events occur on this if we block in the write */
d = i->display;
/* flush pending data so we don't get error deleting the image */
flushimage(d, 0);
a = bufimage(d, 1+4);
if(a == 0)
return -1;
a[0] = 'f';
BPLONG(a+1, i->id);
if(i->screen){
w = d->windows;
if(w == i)
d->windows = i->next;
else
while(w){
if(w->next == i){
w->next = i->next;
break;
}
w = w->next;
}
}
if(flushimage(d, i->screen!=0) < 0)
return -1;
return 0;
}
int
freeimage(Image *i)
{
int ret;
ret = _freeimage1(i);
free(i);
return ret;
}