123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #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 uint32_t */
- uint32_t
- rep(uint32_t v, int n)
- {
- int o;
- uint32_t 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, uint8_t 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[])
- {
- uint8_t 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);
- }
|