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