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