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