talloc.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
talloc.c (4188B) | |
--- | |
1 #include <u.h> | |
2 #include <libc.h> | |
3 #include <draw.h> | |
4 | |
5 Image* | |
6 allocimage(Display *d, Rectangle r, u32int chan, int repl, u32int val) | |
7 { | |
8 return _allocimage(nil, d, r, chan, repl, val, 0, 0); | |
9 } | |
10 | |
11 Image* | |
12 _allocimage(Image *ai, Display *d, Rectangle r, u32int chan, int repl, u… | |
13 { | |
14 uchar *a; | |
15 char *err; | |
16 Image *i; | |
17 Rectangle clipr; | |
18 int id; | |
19 int depth; | |
20 | |
21 err = 0; | |
22 i = 0; | |
23 | |
24 if(chan == 0){ | |
25 werrstr("bad channel descriptor"); | |
26 return nil; | |
27 } | |
28 | |
29 depth = chantodepth(chan); | |
30 if(depth == 0){ | |
31 err = "bad channel descriptor"; | |
32 Error: | |
33 if(err) | |
34 werrstr("allocimage: %s", err); | |
35 else | |
36 werrstr("allocimage: %r"); | |
37 free(i); | |
38 return 0; | |
39 } | |
40 | |
41 /* flush pending data so we don't get error allocating the image… | |
42 flushimage(d, 0); | |
43 a = bufimage(d, 1+4+4+1+4+1+4*4+4*4+4); | |
44 if(a == 0) | |
45 goto Error; | |
46 d->imageid++; | |
47 id = d->imageid; | |
48 a[0] = 'b'; | |
49 BPLONG(a+1, id); | |
50 BPLONG(a+5, screenid); | |
51 a[9] = refresh; | |
52 BPLONG(a+10, chan); | |
53 a[14] = repl; | |
54 BPLONG(a+15, r.min.x); | |
55 BPLONG(a+19, r.min.y); | |
56 BPLONG(a+23, r.max.x); | |
57 BPLONG(a+27, r.max.y); | |
58 if(repl) | |
59 /* huge but not infinite, so various offsets will leave … | |
60 clipr = Rect(-0x3FFFFFFF, -0x3FFFFFFF, 0x3FFFFFFF, 0x3FF… | |
61 else | |
62 clipr = r; | |
63 BPLONG(a+31, clipr.min.x); | |
64 BPLONG(a+35, clipr.min.y); | |
65 BPLONG(a+39, clipr.max.x); | |
66 BPLONG(a+43, clipr.max.y); | |
67 BPLONG(a+47, val); | |
68 if(flushimage(d, 0) < 0) | |
69 goto Error; | |
70 | |
71 if(ai) | |
72 i = ai; | |
73 else{ | |
74 i = malloc(sizeof(Image)); | |
75 if(i == nil){ | |
76 a = bufimage(d, 1+4); | |
77 if(a){ | |
78 a[0] = 'f'; | |
79 BPLONG(a+1, id); | |
80 flushimage(d, 0); | |
81 } | |
82 goto Error; | |
83 } | |
84 } | |
85 i->display = d; | |
86 i->id = id; | |
87 i->depth = depth; | |
88 i->chan = chan; | |
89 i->r = r; | |
90 i->clipr = clipr; | |
91 i->repl = repl; | |
92 i->screen = 0; | |
93 i->next = 0; | |
94 return i; | |
95 } | |
96 | |
97 Image* | |
98 namedimage(Display *d, char *name) | |
99 { | |
100 uchar *a; | |
101 char *err, buf[12*12+1]; | |
102 Image *i; | |
103 int id, n; | |
104 u32int chan; | |
105 | |
106 err = 0; | |
107 i = 0; | |
108 | |
109 n = strlen(name); | |
110 if(n >= 256){ | |
111 err = "name too long"; | |
112 Error: | |
113 if(err) | |
114 werrstr("namedimage: %s", err); | |
115 else | |
116 werrstr("namedimage: %r"); | |
117 if(i) | |
118 free(i); | |
119 return 0; | |
120 } | |
121 /* flush pending data so we don't get error allocating the image… | |
122 flushimage(d, 0); | |
123 a = bufimage(d, 1+4+1+n+1); | |
124 if(a == 0) | |
125 goto Error; | |
126 d->imageid++; | |
127 id = d->imageid; | |
128 a[0] = 'n'; | |
129 BPLONG(a+1, id); | |
130 a[5] = n; | |
131 memmove(a+6, name, n); | |
132 a[6+n] = 'I'; | |
133 if(flushimage(d, 0) < 0) | |
134 goto Error; | |
135 if(_displayrddraw(d, buf, sizeof buf) < 12*12) | |
136 goto Error; | |
137 buf[12*12] = '\0'; | |
138 | |
139 i = malloc(sizeof(Image)); | |
140 if(i == nil){ | |
141 Error1: | |
142 a = bufimage(d, 1+4); | |
143 if(a){ | |
144 a[0] = 'f'; | |
145 BPLONG(a+1, id); | |
146 flushimage(d, 0); | |
147 } | |
148 goto Error; | |
149 } | |
150 i->display = d; | |
151 i->id = id; | |
152 if((chan=strtochan(buf+2*12))==0){ | |
153 werrstr("bad channel '%.12s' from devdraw", buf+2*12); | |
154 goto Error1; | |
155 } | |
156 i->chan = chan; | |
157 i->depth = chantodepth(chan); | |
158 i->repl = atoi(buf+3*12); | |
159 i->r.min.x = atoi(buf+4*12); | |
160 i->r.min.y = atoi(buf+5*12); | |
161 i->r.max.x = atoi(buf+6*12); | |
162 i->r.max.y = atoi(buf+7*12); | |
163 i->clipr.min.x = atoi(buf+8*12); | |
164 i->clipr.min.y = atoi(buf+9*12); | |
165 i->clipr.max.x = atoi(buf+10*12); | |
166 i->clipr.max.y = atoi(buf+11*12); | |
167 i->screen = 0; | |
168 i->next = 0; | |
169 return i; | |
170 } | |
171 | |
172 int | |
173 nameimage(Image *i, char *name, int in) | |
174 { | |
175 uchar *a; | |
176 int n; | |
177 | |
178 n = strlen(name); | |
179 a = bufimage(i->display, 1+4+1+1+n); | |
180 if(a == 0) | |
181 return 0; | |
182 a[0] = 'N'; | |
183 BPLONG(a+1, i->id); | |
184 a[5] = in; | |
185 a[6] = n; | |
186 memmove(a+7, name, n); | |
187 if(flushimage(i->display, 0) < 0) | |
188 return 0; | |
189 return 1; | |
190 } | |
191 | |
192 int | |
193 _freeimage1(Image *i) | |
194 { | |
195 uchar *a; | |
196 Display *d; | |
197 Image *w; | |
198 | |
199 if(i == 0 || i->display == 0) | |
200 return 0; | |
201 /* make sure no refresh events occur on this if we block in the … | |
202 d = i->display; | |
203 /* flush pending data so we don't get error deleting the image */ | |
204 flushimage(d, 0); | |
205 a = bufimage(d, 1+4); | |
206 if(a == 0) | |
207 return -1; | |
208 a[0] = 'f'; | |
209 BPLONG(a+1, i->id); | |
210 if(i->screen){ | |
211 w = d->windows; | |
212 if(w == i) | |
213 d->windows = i->next; | |
214 else | |
215 while(w){ | |
216 if(w->next == i){ | |
217 w->next = i->next; | |
218 break; | |
219 } | |
220 w = w->next; | |
221 } | |
222 } | |
223 if(flushimage(d, i->screen!=0) < 0) | |
224 return -1; | |
225 | |
226 return 0; | |
227 } | |
228 | |
229 int | |
230 freeimage(Image *i) | |
231 { | |
232 int ret; | |
233 | |
234 if(i == nil) | |
235 return 0; | |
236 if(i == screen) | |
237 abort(); | |
238 ret = _freeimage1(i); | |
239 free(i); | |
240 return ret; | |
241 } |