/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include #include #include Image* allocimage(Display *d, Rectangle r, uint32_t chan, int repl, uint32_t val) { Image* i; i = _allocimage(nil, d, r, chan, repl, val, 0, 0); if (i) setmalloctag(i, getcallerpc()); return i; } Image* _allocimage(Image *ai, Display *d, Rectangle r, uint32_t chan, int repl, uint32_t val, int screenid, int refresh) { uint8_t *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; } int nameimage(Image *i, char *name, int in) { uint8_t *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) { uint8_t *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; }