xref: /plan9/sys/src/cmd/colors.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
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 #include <event.h>
5*7dd7cddfSDavid du Colombier 
6*7dd7cddfSDavid du Colombier int nbit, npix;
7*7dd7cddfSDavid du Colombier Image *pixel;
8*7dd7cddfSDavid du Colombier Rectangle crect[256];
9*7dd7cddfSDavid du Colombier 
10*7dd7cddfSDavid du Colombier Image *color[256];
11*7dd7cddfSDavid du Colombier 
12*7dd7cddfSDavid du Colombier void
eresized(int new)13*7dd7cddfSDavid du Colombier eresized(int new)
14*7dd7cddfSDavid du Colombier {
15*7dd7cddfSDavid du Colombier 	int x, y, i, n, nx, ny;
16*7dd7cddfSDavid du Colombier 	Rectangle r, b;
17*7dd7cddfSDavid du Colombier 
18*7dd7cddfSDavid du Colombier 	if(new && getwindow(display, Refnone) < 0){
19*7dd7cddfSDavid du Colombier 		fprint(2, "colors: can't reattach to window: %r\n");
20*7dd7cddfSDavid du Colombier 		exits("resized");
21*7dd7cddfSDavid du Colombier 	}
22*7dd7cddfSDavid du Colombier 	if(screen->depth > 8){
23*7dd7cddfSDavid du Colombier 		n = 256;
24*7dd7cddfSDavid du Colombier 		nx = 16;
25*7dd7cddfSDavid du Colombier 	}else{
26*7dd7cddfSDavid du Colombier 		n = 1<<screen->depth;
27*7dd7cddfSDavid du Colombier 		nx = 1<<(screen->depth/2);
28*7dd7cddfSDavid du Colombier 	}
29*7dd7cddfSDavid du Colombier 
30*7dd7cddfSDavid du Colombier 	ny = n/nx;
31*7dd7cddfSDavid du Colombier 	draw(screen, screen->r, display->white, nil, ZP);
32*7dd7cddfSDavid du Colombier 	r = insetrect(screen->r, 5);
33*7dd7cddfSDavid du Colombier 	r.min.y+=20;
34*7dd7cddfSDavid du Colombier 	b.max.y=r.min.y;
35*7dd7cddfSDavid du Colombier 	for(i=n-1, y=0; y!=ny; y++){
36*7dd7cddfSDavid du Colombier 		b.min.y=b.max.y;
37*7dd7cddfSDavid du Colombier 		b.max.y=r.min.y+(r.max.y-r.min.y)*(y+1)/ny;
38*7dd7cddfSDavid du Colombier 		b.max.x=r.min.x;
39*7dd7cddfSDavid du Colombier 		for(x=0; x!=nx; x++, --i){
40*7dd7cddfSDavid du Colombier 			b.min.x=b.max.x;
41*7dd7cddfSDavid du Colombier 			b.max.x=r.min.x+(r.max.x-r.min.x)*(x+1)/nx;
42*7dd7cddfSDavid du Colombier 			crect[i]=insetrect(b, 1);
43*7dd7cddfSDavid du Colombier 			draw(screen, crect[i], color[i], nil, ZP);
44*7dd7cddfSDavid du Colombier 		}
45*7dd7cddfSDavid du Colombier 	}
46*7dd7cddfSDavid du Colombier 	flushimage(display, 1);
47*7dd7cddfSDavid du Colombier }
48*7dd7cddfSDavid du Colombier 
49*7dd7cddfSDavid du Colombier char *buttons[] =
50*7dd7cddfSDavid du Colombier {
51*7dd7cddfSDavid du Colombier 	"exit",
52*7dd7cddfSDavid du Colombier 	0
53*7dd7cddfSDavid du Colombier };
54*7dd7cddfSDavid du Colombier 
55*7dd7cddfSDavid du Colombier ulong
grey(int i)56*7dd7cddfSDavid du Colombier grey(int i)
57*7dd7cddfSDavid du Colombier {
58*7dd7cddfSDavid du Colombier 	if(i < 0)
59*7dd7cddfSDavid du Colombier 		return grey(0);
60*7dd7cddfSDavid du Colombier 	if(i > 255)
61*7dd7cddfSDavid du Colombier 		return grey(255);
62*7dd7cddfSDavid du Colombier 	return (i<<16)+(i<<8)+i;
63*7dd7cddfSDavid du Colombier }
64*7dd7cddfSDavid du Colombier 
65*7dd7cddfSDavid du Colombier Menu menu =
66*7dd7cddfSDavid du Colombier {
67*7dd7cddfSDavid du Colombier 	buttons
68*7dd7cddfSDavid du Colombier };
69*7dd7cddfSDavid du Colombier 
70*7dd7cddfSDavid du Colombier int
71*7dd7cddfSDavid du Colombier dither[16] =  {
72*7dd7cddfSDavid du Colombier 	0, 8, 2, 10,
73*7dd7cddfSDavid du Colombier 	12, 4, 14, 6,
74*7dd7cddfSDavid du Colombier 	3, 11, 1, 9,
75*7dd7cddfSDavid du Colombier 	15, 7, 13, 5
76*7dd7cddfSDavid du Colombier };
77*7dd7cddfSDavid du Colombier 
78*7dd7cddfSDavid du Colombier void
main(int argc,char * argv[])79*7dd7cddfSDavid du Colombier main(int argc, char *argv[])
80*7dd7cddfSDavid du Colombier {
81*7dd7cddfSDavid du Colombier 	Point p;
82*7dd7cddfSDavid du Colombier 	Mouse m;
83*7dd7cddfSDavid du Colombier 	int i, j, k, l, n, ramp, prev;
84*7dd7cddfSDavid du Colombier 	char buf[100];
85*7dd7cddfSDavid du Colombier 	char *fmt;
86*7dd7cddfSDavid du Colombier 	Image *dark;
87*7dd7cddfSDavid du Colombier 	ulong rgb;
88*7dd7cddfSDavid du Colombier 
89*7dd7cddfSDavid du Colombier 	ramp = 0;
90*7dd7cddfSDavid du Colombier 
91*7dd7cddfSDavid du Colombier 	fmt = "index %3d r %3lud g %3lud b %3lud 0x%.8luX        ";
92*7dd7cddfSDavid du Colombier 	ARGBEGIN{
93*7dd7cddfSDavid du Colombier 	default:
94*7dd7cddfSDavid du Colombier 		goto Usage;
95*7dd7cddfSDavid du Colombier 	case 'x':
96*7dd7cddfSDavid du Colombier 		fmt = "index %2luX r %3luX g %3luX b %3luX 0x%.8luX       ";
97*7dd7cddfSDavid du Colombier 		break;
98*7dd7cddfSDavid du Colombier 	case 'r':
99*7dd7cddfSDavid du Colombier 		ramp = 1;
100*7dd7cddfSDavid du Colombier 		break;
101*7dd7cddfSDavid du Colombier 	}ARGEND
102*7dd7cddfSDavid du Colombier 
103*7dd7cddfSDavid du Colombier 	if(argc){
104*7dd7cddfSDavid du Colombier 	Usage:
105*7dd7cddfSDavid du Colombier 		fprint(2, "Usage: %s [-rx]\n", argv0);
106*7dd7cddfSDavid du Colombier 		exits("usage");
107*7dd7cddfSDavid du Colombier 	}
108*7dd7cddfSDavid du Colombier 
109*7dd7cddfSDavid du Colombier 	if(initdraw(nil, nil, "colors") < 0)
110*7dd7cddfSDavid du Colombier 		sysfatal("initdraw failed: %r");
111*7dd7cddfSDavid du Colombier 	einit(Emouse);
112*7dd7cddfSDavid du Colombier 
113*7dd7cddfSDavid du Colombier 	for(i=0; i<256; i++){
114*7dd7cddfSDavid du Colombier 		if(ramp){
115*7dd7cddfSDavid du Colombier 			if(screen->chan == CMAP8){
116*7dd7cddfSDavid du Colombier 				/* dither the fine grey */
117*7dd7cddfSDavid du Colombier 				j = i-(i%17);
118*7dd7cddfSDavid du Colombier 				dark = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (grey(j)<<8)+0xFF);
119*7dd7cddfSDavid du Colombier 				color[i] = allocimage(display, Rect(0,0,4,4), screen->chan, 1, (grey(j+17)<<8)+0xFF);
120*7dd7cddfSDavid du Colombier 				for(j=0; j<16; j++){
121*7dd7cddfSDavid du Colombier 					k = j%4;
122*7dd7cddfSDavid du Colombier 					l = j/4;
123*7dd7cddfSDavid du Colombier 					if(dither[j] > (i%17))
124*7dd7cddfSDavid du Colombier 						draw(color[i], Rect(k, l, k+1, l+1), dark, nil, ZP);
125*7dd7cddfSDavid du Colombier 				}
126*7dd7cddfSDavid du Colombier 				freeimage(dark);
127*7dd7cddfSDavid du Colombier 			}else
128*7dd7cddfSDavid du Colombier 				color[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (grey(i)<<8)+0xFF);
129*7dd7cddfSDavid du Colombier 		}else
130*7dd7cddfSDavid du Colombier 			color[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (cmap2rgb(i)<<8)+0xFF);
131*7dd7cddfSDavid du Colombier 		if(color[i] == nil)
132*7dd7cddfSDavid du Colombier 			sysfatal("can't allocate image: %r");
133*7dd7cddfSDavid du Colombier 	}
134*7dd7cddfSDavid du Colombier 	eresized(0);
135*7dd7cddfSDavid du Colombier 	prev = -1;
136*7dd7cddfSDavid du Colombier 	for(;;){
137*7dd7cddfSDavid du Colombier 		m = emouse();
138*7dd7cddfSDavid du Colombier 		switch(m.buttons){
139*7dd7cddfSDavid du Colombier 		case 1:
140*7dd7cddfSDavid du Colombier 			while(m.buttons){
141*7dd7cddfSDavid du Colombier 				if(screen->depth > 8)
142*7dd7cddfSDavid du Colombier 					n = 256;
143*7dd7cddfSDavid du Colombier 				else
144*7dd7cddfSDavid du Colombier 					n = 1<<screen->depth;
145*7dd7cddfSDavid du Colombier 				for(i=0; i!=n; i++)
146*7dd7cddfSDavid du Colombier 					if(i!=prev && ptinrect(m.xy, crect[i])){
147*7dd7cddfSDavid du Colombier 						if(ramp)
148*7dd7cddfSDavid du Colombier 							rgb = grey(i);
149*7dd7cddfSDavid du Colombier 						else
150*7dd7cddfSDavid du Colombier 							rgb = cmap2rgb(i);
151*7dd7cddfSDavid du Colombier 						sprint(buf, fmt,
152*7dd7cddfSDavid du Colombier 							i,
153*7dd7cddfSDavid du Colombier 							(rgb>>16)&0xFF,
154*7dd7cddfSDavid du Colombier 							(rgb>>8)&0xFF,
155*7dd7cddfSDavid du Colombier 							rgb&0xFF,
156*7dd7cddfSDavid du Colombier 							(rgb<<8) | 0xFF);
157*7dd7cddfSDavid du Colombier 						p = addpt(screen->r.min, Pt(2,2));
158*7dd7cddfSDavid du Colombier 						draw(screen, Rpt(p, addpt(p, stringsize(font, buf))), display->white, nil, p);
159*7dd7cddfSDavid du Colombier 						string(screen, p, display->black, ZP, font, buf);
160*7dd7cddfSDavid du Colombier 						prev=i;
161*7dd7cddfSDavid du Colombier 						break;
162*7dd7cddfSDavid du Colombier 					}
163*7dd7cddfSDavid du Colombier 				m = emouse();
164*7dd7cddfSDavid du Colombier 			}
165*7dd7cddfSDavid du Colombier 			break;
166*7dd7cddfSDavid du Colombier 
167*7dd7cddfSDavid du Colombier 		case 4:
168*7dd7cddfSDavid du Colombier 			switch(emenuhit(3, &m, &menu)){
169*7dd7cddfSDavid du Colombier 			case 0:
170*7dd7cddfSDavid du Colombier 				exits(0);
171*7dd7cddfSDavid du Colombier 			}
172*7dd7cddfSDavid du Colombier 		}
173*7dd7cddfSDavid du Colombier 	}
174*7dd7cddfSDavid du Colombier }
175