Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | 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
	return _allocimage(nil, d, r, chan, repl, val, 0, 0);
9
}
10
 
11
Image*
12
_allocimage(Image *ai, Display *d, Rectangle r, ulong chan, int repl, ulong val, int screenid, int refresh)
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 it huge, not overflow */
60
		clipr = Rect(-0x3FFFFFFF, -0x3FFFFFFF, 0x3FFFFFFF, 0x3FFFFFFF);
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
	ulong 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);
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
	if(flushimage(d, 0) < 0)
133
		goto Error;
134
 
135
	if(pread(d->ctlfd, buf, sizeof buf, 0) < 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)
200
		return 0;
201
	/* make sure no refresh events occur on this if we block in the write */
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
	ret = _freeimage1(i);
235
	free(i);
236
	return ret;
237
}