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
/*
6
 * int getcmap(int id, char *file, unsigned char *buf)
7
 *	Read a colormap from the given file into the buffer.
8
 *	Returns 1 on success, 0 otherwise.
9
 *	Goes to unglaublich length to figure out what the file name means:
10
 *	If the name is "screen" or "display" or "vga", reads the colormap from /dev/draw/id/colormap.
11
 *	If the name is "gamma",returns gamma=2.3 colormap
12
 *	If the name is "gamma###", returns gamma=#### colormap
13
 *	Ditto for rgamma, for reverse video.
14
 *	Looks for the file in a list of directories (given below).
15
 */
16
 
17
char *cmapdir[] = {
18
	"",
19
	"/lib/cmap/",
20
 
21
};
22
 
23
int
24
getcmap(int id, char *f, unsigned char *buf)
25
{
26
	char name[512];
27
	char *s, *lines[256], *fields[4];
28
	int cmap, i, j, n, v, rev;
29
	double gamma;
30
 
31
	cmap = -1;
32
	for(i=0; cmapdir[i]!=nil ;i++){
33
		snprint(name, sizeof name, "%s%s", cmapdir[i], f);
34
		if((cmap = open(name, OREAD)) >= 0)
35
			break;
36
	}
37
 
38
	if(cmap == -1){
39
		if(strcmp(name, "screen")==0 || strcmp(name, "display")==0 || strcmp(name, "vga")==0){
40
			snprint(name, sizeof name, "/dev/draw/%d/colormap", id);
41
			cmap = open(name, OREAD);
42
			if(cmap < 0)
43
				return 0;
44
		}
45
	}
46
 
47
	if(cmap==-1){ /* could be gamma or gamma<number> or fb */
48
		if(strncmp(f, "gamma", 5)==0){
49
			rev=0;
50
			f+=5;
51
		}else if(strncmp(f, "rgamma", 6)==0){
52
			rev = 1;
53
			f+=6;
54
		}else
55
			return 0;
56
		if(*f == '\0')
57
			gamma=2.3;
58
		else{
59
			if(strspn(f, "0123456789.") != strlen(f))
60
				return 0;
61
			gamma = atof(f);
62
		}
63
		for(i=0; i!=256; i++){
64
			v=255.*pow(i/255., 1./gamma);
65
			if(rev)
66
				v=255-v;
67
			buf[0] = buf[1] = buf[2] = v;
68
			buf += 3;
69
		}
70
		return 1;
71
	}
72
 
73
	s = malloc(20000);
74
	n = readn(cmap, s, 20000-1);
75
	if(n <= 0)
76
		return 0;
77
	s[n] = '\0';
78
	if(getfields(s, lines, 256, 0, "\n") != 256)
79
		return 0;
80
	for(i=0; i<256; i++){
81
		if(getfields(lines[i], fields, 4, 1, " \t") != 4)
82
			return 0;
83
		if(atoi(fields[0]) != i)
84
			return 0;
85
		for(j=0; j<3; j++)
86
			buf[3*i+j] = atoi(fields[j+1]);
87
	}
88
	return 1;
89
}
90
 
91
/* replicate (from top) value in v (n bits) until it fills a ulong */
92
ulong
93
rep(ulong v, int n)
94
{
95
	int o;
96
	ulong rv;
97
 
98
	rv = 0;
99
	for(o=32-n; o>=0; o-=n)
100
		rv |= v<<o;
101
	if(o != -n)
102
		rv |= v>>-o;
103
	return rv;
104
}
105
 
106
void
107
putcmap(int id, uchar cmap[256*3])
108
{
109
	char *s, *t;
110
	int i, fd;
111
	char name[64];
112
 
113
	snprint(name, sizeof name, "/dev/draw/%d/colormap", id);
114
	fd = open(name, OWRITE);
115
	if(fd < 0)
116
		sysfatal("can't open colormap file: %r");
117
	s = malloc(20000);
118
	t = s;
119
	for(i = 0; i<256; i++)
120
		t += sprint(t, "%d %d %d %d\n", i, cmap[3*i+0], cmap[3*i+1], cmap[3*i+2]);
121
	if(write(fd, s, t-s) != t-s)
122
		sysfatal("writing color map: %r");
123
	close(fd);
124
}
125
 
126
void
127
main(int argc, char *argv[])
128
{
129
	uchar cmapbuf[256*3];
130
	char *map, buf[12*12+1];
131
	int fd, id;
132
 
133
	if(argc>2){
134
		fprint(2, "Usage: %s colormap\n", argv[0]);
135
		exits("usage");
136
	}
137
	map = "rgbv";
138
	if(argc > 1)
139
		map = argv[1];
140
 
141
	fd = open("/dev/draw/new", OREAD);
142
	if(fd < 0 || read(fd, buf, sizeof buf) != 12*12)
143
		sysfatal("can't connect to display: %r");
144
	id = atoi(buf+0*12);
145
	if(strncmp(buf+2*12, "         m8 ", 12) != 0)
146
		sysfatal("can't set colormap except on CMAP8 (m8) displays; this one is %.12s", buf+2*12);
147
 
148
	if(getcmap(id, map, cmapbuf) == 0){
149
		fprint(2, "%s: can't find %s\n", argv[0], map);
150
		exits("not found");
151
	}
152
 
153
	putcmap(id, cmapbuf);
154
	exits(0);
155
}