5bc9b0c3ca
Fix inconsistencies between programs and their usage messages, correct instances where information seems to be missing or lost. This includes missing arguments, making usage consistent with manuals, and so on.
156 lines
3.2 KiB
C
156 lines
3.2 KiB
C
#include <u.h>
|
|
#include <libc.h>
|
|
#include <draw.h>
|
|
|
|
/*
|
|
* int getcmap(int id, char *file, unsigned char *buf)
|
|
* Read a colormap from the given file into the buffer.
|
|
* Returns 1 on success, 0 otherwise.
|
|
* Goes to unglaublich length to figure out what the file name means:
|
|
* If the name is "screen" or "display" or "vga", reads the colormap from /dev/draw/id/colormap.
|
|
* If the name is "gamma",returns gamma=2.3 colormap
|
|
* If the name is "gamma###", returns gamma=#### colormap
|
|
* Ditto for rgamma, for reverse video.
|
|
* Looks for the file in a list of directories (given below).
|
|
*/
|
|
|
|
char *cmapdir[] = {
|
|
"",
|
|
"/lib/cmap/",
|
|
0
|
|
};
|
|
|
|
int
|
|
getcmap(int id, char *f, unsigned char *buf)
|
|
{
|
|
char name[512];
|
|
char *s, *lines[256], *fields[4];
|
|
int cmap, i, j, n, v, rev;
|
|
double gamma;
|
|
|
|
cmap = -1;
|
|
for(i=0; cmapdir[i]!=nil ;i++){
|
|
snprint(name, sizeof name, "%s%s", cmapdir[i], f);
|
|
if((cmap = open(name, OREAD)) >= 0)
|
|
break;
|
|
}
|
|
|
|
if(cmap == -1){
|
|
if(strcmp(name, "screen")==0 || strcmp(name, "display")==0 || strcmp(name, "vga")==0){
|
|
snprint(name, sizeof name, "/dev/draw/%d/colormap", id);
|
|
cmap = open(name, OREAD);
|
|
if(cmap < 0)
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if(cmap==-1){ /* could be gamma or gamma<number> or fb */
|
|
if(strncmp(f, "gamma", 5)==0){
|
|
rev=0;
|
|
f+=5;
|
|
}else if(strncmp(f, "rgamma", 6)==0){
|
|
rev = 1;
|
|
f+=6;
|
|
}else
|
|
return 0;
|
|
if(*f == '\0')
|
|
gamma=2.3;
|
|
else{
|
|
if(strspn(f, "0123456789.") != strlen(f))
|
|
return 0;
|
|
gamma = atof(f);
|
|
}
|
|
for(i=0; i!=256; i++){
|
|
v=255.*pow(i/255., 1./gamma);
|
|
if(rev)
|
|
v=255-v;
|
|
buf[0] = buf[1] = buf[2] = v;
|
|
buf += 3;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
s = malloc(20000);
|
|
n = readn(cmap, s, 20000-1);
|
|
if(n <= 0)
|
|
return 0;
|
|
s[n] = '\0';
|
|
if(getfields(s, lines, 256, 0, "\n") != 256)
|
|
return 0;
|
|
for(i=0; i<256; i++){
|
|
if(getfields(lines[i], fields, 4, 1, " \t") != 4)
|
|
return 0;
|
|
if(atoi(fields[0]) != i)
|
|
return 0;
|
|
for(j=0; j<3; j++)
|
|
buf[3*i+j] = atoi(fields[j+1]);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/* replicate (from top) value in v (n bits) until it fills a ulong */
|
|
ulong
|
|
rep(ulong v, int n)
|
|
{
|
|
int o;
|
|
ulong rv;
|
|
|
|
rv = 0;
|
|
for(o=32-n; o>=0; o-=n)
|
|
rv |= v<<o;
|
|
if(o != -n)
|
|
rv |= v>>-o;
|
|
return rv;
|
|
}
|
|
|
|
void
|
|
putcmap(int id, uchar cmap[256*3])
|
|
{
|
|
char *s, *t;
|
|
int i, fd;
|
|
char name[64];
|
|
|
|
snprint(name, sizeof name, "/dev/draw/%d/colormap", id);
|
|
fd = open(name, OWRITE);
|
|
if(fd < 0)
|
|
sysfatal("can't open colormap file: %r");
|
|
s = malloc(20000);
|
|
t = s;
|
|
for(i = 0; i<256; i++)
|
|
t += sprint(t, "%d %d %d %d\n", i, cmap[3*i+0], cmap[3*i+1], cmap[3*i+2]);
|
|
if(write(fd, s, t-s) != t-s)
|
|
sysfatal("writing color map: %r");
|
|
close(fd);
|
|
}
|
|
|
|
void
|
|
main(int argc, char *argv[])
|
|
{
|
|
uchar cmapbuf[256*3];
|
|
char *map, buf[12*12+1];
|
|
int fd, id;
|
|
|
|
if(argc>2){
|
|
fprint(2, "usage: %s colormap\n", argv[0]);
|
|
exits("usage");
|
|
}
|
|
map = "rgbv";
|
|
if(argc > 1)
|
|
map = argv[1];
|
|
|
|
fd = open("/dev/draw/new", OREAD);
|
|
if(fd < 0 || read(fd, buf, sizeof buf) != 12*12)
|
|
sysfatal("can't connect to display: %r");
|
|
id = atoi(buf+0*12);
|
|
if(strncmp(buf+2*12, " m8 ", 12) != 0)
|
|
sysfatal("can't set colormap except on CMAP8 (m8) displays; this one is %.12s", buf+2*12);
|
|
|
|
if(getcmap(id, map, cmapbuf) == 0){
|
|
fprint(2, "%s: can't find %s\n", argv[0], map);
|
|
exits("not found");
|
|
}
|
|
|
|
putcmap(id, cmapbuf);
|
|
exits(0);
|
|
}
|