1 #include "lib9.h"
2 #include "draw.h"
3 #include "memdraw.h"
4 #include "memlayer.h"
5
6 Memimage*
memlalloc(Memscreen * s,Rectangle screenr,Refreshfn refreshfn,void * refreshptr,ulong val)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