Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <thread.h>
5 #include <keyboard.h>
6 #include <mouse.h>
8 enum
9 {
10 STACK = 8192
11 };
13 int nbit, npix;
14 Image *pixel;
15 Rectangle crect[256];
16 Image *color[256];
17 char *fmt;
18 int ramp;
20 Mousectl *mousectl;
21 Keyboardctl *keyboardctl;
23 void keyboardthread(void*);
24 void mousethread(void*);
25 void resizethread(void*);
27 ulong
28 grey(int i)
29 {
30 if(i < 0)
31 return grey(0);
32 if(i > 255)
33 return grey(255);
34 return (i<<16)+(i<<8)+i;
35 }
37 int
38 dither[16] = {
39 0, 8, 2, 10,
40 12, 4, 14, 6,
41 3, 11, 1, 9,
42 15, 7, 13, 5
43 };
45 extern int chattydrawclient;
47 void
48 threadmain(int argc, char *argv[])
49 {
50 int i, j, k, l;
51 Image *dark;
53 ramp = 0;
55 fmt = "index %3d r %3lud g %3lud b %3lud 0x%.8luX ";
56 ARGBEGIN{
57 default:
58 goto Usage;
59 case 'D':
60 chattydrawclient = 1;
61 break;
62 case 'x':
63 fmt = "index %2luX r %3luX g %3luX b %3luX 0x%.8luX ";
64 break;
65 case 'r':
66 ramp = 1;
67 break;
68 }ARGEND
70 if(argc){
71 Usage:
72 fprint(2, "Usage: %s [-rx]\n", argv0);
73 threadexitsall("usage");
74 }
76 if(initdraw(0, nil, "colors") < 0)
77 sysfatal("initdraw failed: %r");
79 mousectl = initmouse(nil, display->image);
80 if(mousectl == nil)
81 sysfatal("initmouse: %r");
83 keyboardctl = initkeyboard(nil);
84 if(keyboardctl == nil)
85 sysfatal("initkeyboard: %r");
87 for(i=0; i<256; i++){
88 if(ramp){
89 if(screen->chan == CMAP8){
90 /* dither the fine grey */
91 j = i-(i%17);
92 dark = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (grey(j)<<8)+0xFF);
93 color[i] = allocimage(display, Rect(0,0,4,4), screen->chan, 1, (grey(j+17)<<8)+0xFF);
94 for(j=0; j<16; j++){
95 k = j%4;
96 l = j/4;
97 if(dither[j] > (i%17))
98 draw(color[i], Rect(k, l, k+1, l+1), dark, nil, ZP);
99 }
100 freeimage(dark);
101 }else
102 color[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (grey(i)<<8)+0xFF);
103 }else
104 color[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (cmap2rgb(i)<<8)+0xFF);
105 if(color[i] == nil)
106 sysfatal("can't allocate image: %r");
109 threadcreate(mousethread, nil, STACK);
110 threadcreate(keyboardthread, nil, STACK);
111 threadcreate(resizethread, nil, STACK);
114 void
115 keyboardthread(void *v)
117 Rune r;
119 USED(v);
121 while(recv(keyboardctl->c, &r) >= 0)
125 char *buttons[] =
127 "exit",
129 };
131 Menu menu =
133 buttons
134 };
136 void
137 mousethread(void *v)
139 Point p;
140 Mouse m;
141 int i, n, prev;
142 char buf[100];
143 ulong rgb;
145 prev = -1;
146 while(readmouse(mousectl) >= 0){
147 m = mousectl->m;
148 switch(m.buttons){
149 case 1:
150 while(m.buttons){
151 if(screen->depth > 8)
152 n = 256;
153 else
154 n = 1<<screen->depth;
155 for(i=0; i!=n; i++)
156 if(i!=prev && ptinrect(m.xy, crect[i])){
157 if(ramp)
158 rgb = grey(i);
159 else
160 rgb = cmap2rgb(i);
161 sprint(buf, fmt,
162 i,
163 (rgb>>16)&0xFF,
164 (rgb>>8)&0xFF,
165 rgb&0xFF,
166 (rgb<<8) | 0xFF);
167 p = addpt(screen->r.min, Pt(2,2));
168 draw(screen, Rpt(p, addpt(p, stringsize(font, buf))), display->white, nil, p);
169 string(screen, p, display->black, ZP, font, buf);
170 prev=i;
171 break;
173 readmouse(mousectl);
174 m = mousectl->m;
176 break;
178 case 4:
179 switch(menuhit(3, mousectl, &menu, nil)){
180 case 0:
181 threadexitsall(0);
187 void
188 eresized(int new)
190 int x, y, i, n, nx, ny;
191 Rectangle r, b;
193 if(new && getwindow(display, Refnone) < 0){
194 fprint(2, "colors: can't reattach to window: %r\n");
195 threadexitsall("resized");
197 if(screen->depth > 8){
198 n = 256;
199 nx = 16;
200 }else{
201 n = 1<<screen->depth;
202 nx = 1<<(screen->depth/2);
205 ny = n/nx;
206 draw(screen, screen->r, display->white, nil, ZP);
207 r = insetrect(screen->r, 5);
208 r.min.y+=20;
209 b.max.y=r.min.y;
210 for(i=n-1, y=0; y!=ny; y++){
211 b.min.y=b.max.y;
212 b.max.y=r.min.y+(r.max.y-r.min.y)*(y+1)/ny;
213 b.max.x=r.min.x;
214 for(x=0; x!=nx; x++, --i){
215 b.min.x=b.max.x;
216 b.max.x=r.min.x+(r.max.x-r.min.x)*(x+1)/nx;
217 crect[i]=insetrect(b, 1);
218 draw(screen, crect[i], color[i], nil, ZP);
221 flushimage(display, 1);
224 void
225 resizethread(void *v)
227 ulong x;
229 USED(v);
231 eresized(0);
232 while(recv(mousectl->resizec, &x) >= 0)
233 eresized(1);