xref: /inferno-os/libmemlayer/lalloc-x11.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1 #include "lib9.h"
2 #include "image.h"
3 #include "memimage.h"
4 #include "memlayer.h"
5 
6 #include "../memimage/xmem.h"
7 
8 
9 static ulong colorword;
10 static Memdata colordata = {
11 	nil,
12 	&colorword
13 };
14 
15 static Memimage paint =
16 {
17 	{ 0, 0, 1, 1 },
18 	{ -1000000, -1000000, 10000000, 1000000 },
19 	0,
20 	1,
21 	&colordata,
22 	0,
23 	1,
24 	0,
25 };
26 
27 static Memimage *xpaint;
28 
29 static void
setcolor(int val,int ldepth)30 setcolor(int val, int ldepth)
31 {
32 	int bpp;
33 
34 	paint.ldepth = ldepth;
35 	bpp = 1<<ldepth;
36 	val &= ~(0xFF>>bpp);
37 	/* color is now in low part of word; replicate through pixel */
38 	for(; bpp<32; bpp<<=1)
39 		val |= val<<bpp;
40 	colorword = val;
41 }
42 
43 ulong*
makememones(void)44 makememones(void)
45 {
46 	Xmem *xm;
47 	extern Memimage	screenimage;
48 	extern void drawreset();
49 
50 	if(memones->X)
51 		return;
52 	drawreset();
53 	/* set up screen pixmap */
54 	xm = malloc(sizeof(Xmem));
55 	if(xm == nil){
56 		print("can't alloc for screen pixmap\n");
57 		return;
58 	}
59 	if(screenimage.ldepth == 0)
60 		xm->pmid0 = xscreenid;
61 	else
62 		xm->pmid0 = PMundef;
63 	xm->pmid = xscreenid;
64 	xm->wordp = &xm->word;
65 	screenimage.X = xm;
66 	screenimage.data->data = &xm->word;
67 
68 	memones = allocmemimage(paint.r, paint.ldepth);
69 	memones->clipr = paint.clipr;
70 	memones->repl = 1;
71 	memfillcolor(memones, ~0);
72 
73 	return screenimage.data->data;
74 }
75 
76 Memimage*
memlalloc(Memscreen * s,Rectangle screenr,Refreshfn refreshfn,void * refreshptr,int val)77 memlalloc(Memscreen *s, Rectangle screenr, Refreshfn refreshfn, void *refreshptr, int val)
78 {
79 	Memimage *n;
80 	Memlayer *l;
81 	Xmem *xm, *sxm;
82 
83 	n = malloc(sizeof(Memimage));
84 	if(n == nil)
85 		return nil;
86 
87 	l = malloc(sizeof(Memlayer));
88 	if(l == nil){
89 		free(n);
90 		return nil;
91 	}
92 
93 	xm = malloc(sizeof(Xmem));
94 	if(xm == nil){
95 		free(l);
96 		free(n);
97 		return nil;
98 	}
99 
100 	if(refreshfn) {
101 		l->save = nil;
102 	}
103 	else{
104 		l->save = allocmemimage(screenr, s->image->ldepth);
105 		if(l->save == nil){
106 			free(l);
107 			free(n);
108 			free(xm);
109 			return nil;
110 		}
111 
112 		/* allocmemimage doesn't initialize memory; this paints save area */
113 		if(val >= 0)
114 			memfillcolor(l->save, val);
115 	}
116 
117 	n->r = screenr;
118 	n->clipr = screenr;
119 	n->ldepth = s->image->ldepth;
120 	n->repl = 0;
121 	n->data = s->image->data;
122 	n->zero = s->image->zero;
123 	n->width = s->image->width;
124 	n->layer = l;
125 	n->X = xm;
126 
127 	sxm = s->image->X;
128 	xm->pmid0 = sxm->pmid0;
129 	xm->pmid = sxm->pmid;
130 	xm->flag = 0;
131 	xm->wordp = sxm->wordp;
132 
133 	l->screen = s;
134 	l->refreshfn = refreshfn;
135 	l->screenr = screenr;
136 	l->delta = Pt(0,0);
137 
138 	/* start with new window behind all existing ones */
139 	l->front = s->rearmost;
140 	l->rear = nil;
141 	if(s->rearmost)
142 		s->rearmost->layer->rear = n;
143 	s->rearmost = n;
144 	if(s->frontmost == nil)
145 		s->frontmost = n;
146 	l->clear = 0;
147 
148 	/* don't set it until we're done */
149 	l->refreshptr = nil;
150 
151 	/* now pull new window to front */
152 	memltofront(n);
153 
154 	/* now we're done */
155 	l->refreshptr = refreshptr;
156 
157 	/*
158 	 * paint with requested color.
159 	 * previously exposed areas are already right
160 	 * if this window has backing store, but just painting
161 	 * the whole thing is simplest.
162 	 */
163 
164 	if(val >= 0){
165 		setcolor(val, s->image->ldepth);
166 		if(xpaint == nil){
167 			xpaint = allocmemimage(paint.r, paint.ldepth);
168 			if(xpaint == nil) {
169 				if(l->save != nil)
170 					freememimage(l->save);
171 				free(l);
172 				free(n);
173 				free(xm);
174 				return nil;
175 			}
176 			xpaint->clipr = paint.clipr;
177 			xpaint->repl = 1;
178 		}
179 		((Xmem*)(xpaint->X))->word = colorword;
180 		((Xmem*)(xpaint->X))->flag |= XXonepixel;
181 		memfillcolor(xpaint, val);
182 		memdraw(n, n->r, xpaint, n->r.min, memones, n->r.min, S);
183 	}
184 	return n;
185 }
186