]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/getmap.c
vmx: reset virtio queue state on device reset
[plan9front.git] / sys / src / cmd / getmap.c
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         0
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 }