|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include <draw.h> | 
|  | #include <memdraw.h> | 
|  | #include <memlayer.h> | 
|  |  | 
|  | Memimage* | 
|  | memlalloc(Memscreen *s, Rectangle screenr, Refreshfn refreshfn, void *refreshptr, u32int val) | 
|  | { | 
|  | Memlayer *l; | 
|  | Memimage *n; | 
|  | static Memimage *paint; | 
|  |  | 
|  | if(paint == nil){ | 
|  | paint = allocmemimage(Rect(0,0,1,1), RGBA32); | 
|  | if(paint == nil) | 
|  | return nil; | 
|  | paint->flags |= Frepl; | 
|  | paint->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF); | 
|  | } | 
|  |  | 
|  | n = allocmemimaged(screenr, s->image->chan, s->image->data, nil); | 
|  | if(n == nil) | 
|  | return nil; | 
|  | l = malloc(sizeof(Memlayer)); | 
|  | if(l == nil){ | 
|  | free(n); | 
|  | return nil; | 
|  | } | 
|  |  | 
|  | l->screen = s; | 
|  | if(refreshfn) | 
|  | l->save = nil; | 
|  | else{ | 
|  | l->save = allocmemimage(screenr, s->image->chan); | 
|  | if(l->save == nil){ | 
|  | free(l); | 
|  | free(n); | 
|  | return nil; | 
|  | } | 
|  | /* allocmemimage doesn't initialize memory; this paints save area */ | 
|  | if(val != DNofill) | 
|  | memfillcolor(l->save, val); | 
|  | } | 
|  | l->refreshfn = refreshfn; | 
|  | l->refreshptr = nil;	/* don't set it until we're done */ | 
|  | l->screenr = screenr; | 
|  | l->delta = Pt(0,0); | 
|  |  | 
|  | n->data->ref++; | 
|  | n->zero = s->image->zero; | 
|  | n->width = s->image->width; | 
|  | n->layer = l; | 
|  |  | 
|  | /* start with new window behind all existing ones */ | 
|  | l->front = s->rearmost; | 
|  | l->rear = nil; | 
|  | if(s->rearmost) | 
|  | s->rearmost->layer->rear = n; | 
|  | s->rearmost = n; | 
|  | if(s->frontmost == nil) | 
|  | s->frontmost = n; | 
|  | l->clear = 0; | 
|  |  | 
|  | /* now pull new window to front */ | 
|  | _memltofrontfill(n, val != DNofill); | 
|  | l->refreshptr = refreshptr; | 
|  |  | 
|  | /* | 
|  | * paint with requested color; previously exposed areas are already right | 
|  | * if this window has backing store, but just painting the whole thing is simplest. | 
|  | */ | 
|  | if(val != DNofill){ | 
|  | memsetchan(paint, n->chan); | 
|  | memfillcolor(paint, val); | 
|  | memdraw(n, n->r, paint, n->r.min, nil, n->r.min, S); | 
|  | } | 
|  | return n; | 
|  | } |