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