1 #include "lib9.h" 2 #include "draw.h" 3 #include "memdraw.h" 4 #include "memlayer.h" 5 6 Memimage* 7 memlalloc(Memscreen *s, Rectangle screenr, Refreshfn refreshfn, void *refreshptr, ulong val) 8 { 9 Memlayer *l; 10 Memimage *n; 11 static Memimage *paint; 12 13 if(paint == nil){ 14 paint = allocmemimage(Rect(0,0,1,1), RGBA32); 15 if(paint == nil) 16 return nil; 17 paint->flags |= Frepl; 18 paint->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF); 19 } 20 21 n = allocmemimaged(screenr, s->image->chan, s->image->data); 22 if(n == nil) 23 return nil; 24 l = malloc(sizeof(Memlayer)); 25 if(l == nil){ 26 free(n); 27 return nil; 28 } 29 30 l->screen = s; 31 if(refreshfn) 32 l->save = nil; 33 else{ 34 l->save = allocmemimage(screenr, s->image->chan); 35 if(l->save == nil){ 36 free(l); 37 free(n); 38 return nil; 39 } 40 /* allocmemimage doesn't initialize memory; this paints save area */ 41 if(val != DNofill) 42 memfillcolor(l->save, val); 43 } 44 l->refreshfn = refreshfn; 45 l->refreshptr = nil; /* don't set it until we're done */ 46 l->screenr = screenr; 47 l->delta = Pt(0,0); 48 49 n->data->ref++; 50 n->zero = s->image->zero; 51 n->width = s->image->width; 52 n->layer = l; 53 54 /* start with new window behind all existing ones */ 55 l->front = s->rearmost; 56 l->rear = nil; 57 if(s->rearmost) 58 s->rearmost->layer->rear = n; 59 s->rearmost = n; 60 if(s->frontmost == nil) 61 s->frontmost = n; 62 l->clear = 0; 63 64 /* now pull new window to front */ 65 _memltofrontfill(n, val != DNofill); 66 l->refreshptr = refreshptr; 67 68 /* 69 * paint with requested color; previously exposed areas are already right 70 * if this window has backing store, but just painting the whole thing is simplest. 71 */ 72 if(val != DNofill){ 73 memsetchan(paint, n->chan); 74 memfillcolor(paint, val); 75 memdraw(n, n->r, paint, n->r.min, nil, n->r.min, S); 76 } 77 return n; 78 } 79