Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature-vt/sys/src/libdraw/alloc.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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