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_unix/sys/src/libmemdraw/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
#include <memdraw.h>
5
#include <pool.h>
6
 
7
void
8
memimagemove(void *from, void *to)
9
{
10
	Memdata *md;
11
 
12
	md = *(Memdata**)to;
13
	if(md->base != from){
14
		print("compacted data not right: #%p\n", md->base);
15
		abort();
16
	}
17
	md->base = to;
18
 
19
	/* if allocmemimage changes this must change too */
20
	md->bdata = (uchar*)md->base+sizeof(Memdata*)+sizeof(ulong);
21
}
22
 
23
Memimage*
24
allocmemimaged(Rectangle r, ulong chan, Memdata *md)
25
{
26
	int d;
27
	ulong l;
28
	Memimage *i;
29
 
30
	if(Dx(r) <= 0 || Dy(r) <= 0){
31
		werrstr("bad rectangle %R", r);
32
		return nil;
33
	}
34
	if((d = chantodepth(chan)) == 0) {
35
		werrstr("bad channel descriptor %.8lux", chan);
36
		return nil;
37
	}
38
 
39
	l = wordsperline(r, d);
40
 
41
	i = mallocz(sizeof(Memimage), 1);
42
	if(i == nil)
43
		return nil;
44
 
45
	i->data = md;
46
	i->zero = sizeof(ulong)*l*r.min.y;
47
 
48
	if(r.min.x >= 0)
49
		i->zero += (r.min.x*d)/8;
50
	else
51
		i->zero -= (-r.min.x*d+7)/8;
52
	i->zero = -i->zero;
53
	i->width = l;
54
	i->r = r;
55
	i->clipr = r;
56
	i->flags = 0;
57
	i->layer = nil;
58
	i->cmap = memdefcmap;
59
	if(memsetchan(i, chan) < 0){
60
		free(i);
61
		return nil;
62
	}
63
	return i;
64
}
65
 
66
Memimage*
67
allocmemimage(Rectangle r, ulong chan)
68
{
69
	int d;
70
	uchar *p;
71
	ulong l, nw;
72
	Memdata *md;
73
	Memimage *i;
74
 
75
	if((d = chantodepth(chan)) == 0) {
76
		werrstr("bad channel descriptor %.8lux", chan);
77
		return nil;
78
	}
79
 
80
	l = wordsperline(r, d);
81
	nw = l*Dy(r);
82
	md = malloc(sizeof(Memdata));
83
	if(md == nil)
84
		return nil;
85
 
86
	md->ref = 1;
87
	md->base = poolalloc(imagmem, sizeof(Memdata*)+(1+nw)*sizeof(ulong));
88
	if(md->base == nil){
89
		free(md);
90
		return nil;
91
	}
92
 
93
	p = (uchar*)md->base;
94
	*(Memdata**)p = md;
95
	p += sizeof(Memdata*);
96
 
97
	*(ulong*)p = getcallerpc(&r);
98
	p += sizeof(ulong);
99
 
100
	/* if this changes, memimagemove must change too */
101
	md->bdata = p;
102
	md->allocd = 1;
103
 
104
	i = allocmemimaged(r, chan, md);
105
	if(i == nil){
106
		poolfree(imagmem, md->base);
107
		free(md);
108
		return nil;
109
	}
110
	md->imref = i;
111
	return i;
112
}
113
 
114
void
115
freememimage(Memimage *i)
116
{
117
	if(i == nil)
118
		return;
119
	if(i->data->ref-- == 1 && i->data->allocd){
120
		if(i->data->base)
121
			poolfree(imagmem, i->data->base);
122
		free(i->data);
123
	}
124
	free(i);
125
}
126
 
127
/*
128
 * Wordaddr is deprecated.
129
 */
130
ulong*
131
wordaddr(Memimage *i, Point p)
132
{
133
	return (ulong*) ((uintptr)byteaddr(i, p) & ~(sizeof(ulong)-1));
134
}
135
 
136
uchar*
137
byteaddr(Memimage *i, Point p)
138
{
139
	uchar *a;
140
 
141
	a = i->data->bdata+i->zero+sizeof(ulong)*p.y*i->width;
142
 
143
	if(i->depth < 8){
144
		/*
145
		 * We need to always round down,
146
		 * but C rounds toward zero.
147
		 */
148
		int np;
149
		np = 8/i->depth;
150
		if(p.x < 0)
151
			return a+(p.x-np+1)/np;
152
		else
153
			return a+p.x/np;
154
	}
155
	else
156
		return a+p.x*(i->depth/8);
157
}
158
 
159
int
160
memsetchan(Memimage *i, ulong chan)
161
{
162
	int d;
163
	int t, j, k;
164
	ulong cc;
165
	int bytes;
166
 
167
	if((d = chantodepth(chan)) == 0) {
168
		werrstr("bad channel descriptor");
169
		return -1;
170
	}
171
 
172
	i->depth = d;
173
	i->chan = chan;
174
	i->flags &= ~(Fgrey|Falpha|Fcmap|Fbytes);
175
	bytes = 1;
176
	for(cc=chan, j=0, k=0; cc; j+=NBITS(cc), cc>>=8, k++){
177
		t=TYPE(cc);
178
		if(t < 0 || t >= NChan){
179
			werrstr("bad channel string");
180
			return -1;
181
		}
182
		if(t == CGrey)
183
			i->flags |= Fgrey;
184
		if(t == CAlpha)
185
			i->flags |= Falpha;
186
		if(t == CMap && i->cmap == nil){
187
			i->cmap = memdefcmap;
188
			i->flags |= Fcmap;
189
		}
190
 
191
		i->shift[t] = j;
192
		i->mask[t] = (1<<NBITS(cc))-1;
193
		i->nbits[t] = NBITS(cc);
194
		if(NBITS(cc) != 8)
195
			bytes = 0;
196
	}
197
	i->nchan = k;
198
	if(bytes)
199
		i->flags |= Fbytes;
200
	return 0;
201
}