ttcolors.c - plan9port - [fork] Plan 9 from user space
HTML git clone git://src.adamsgaard.dk/plan9port
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
ttcolors.c (4140B)
---
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <thread.h>
5 #include <keyboard.h>
6 #include <mouse.h>
7
8 enum
9 {
10 STACK = 8192
11 };
12
13 int nbit, npix;
14 Image *pixel;
15 Rectangle crect[256];
16 Image *color[256];
17 char *fmt;
18 int ramp;
19
20 Mousectl *mousectl;
21 Keyboardctl *keyboardctl;
22
23 void keyboardthread(void*);
24 void mousethread(void*);
25 void resizethread(void*);
26
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 }
36
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 };
44
45 extern int chattydrawclient;
46
47 int
48 threadmaybackground(void)
49 {
50 return 1;
51 }
52
53 void
54 threadmain(int argc, char *argv[])
55 {
56 int i, j, k, l;
57 Image *dark;
58
59 ramp = 0;
60
61 fmt = "index %3d r %3lud g %3lud b %3lud 0x%.8luX ";
62 ARGBEGIN{
63 default:
64 goto Usage;
65 case 'D':
66 chattydrawclient = 1;
67 break;
68 case 'x':
69 fmt = "index %2luX r %3luX g %3luX b %3luX 0x%.8luX ";
70 break;
71 case 'r':
72 ramp = 1;
73 break;
74 }ARGEND
75
76 if(argc){
77 Usage:
78 fprint(2, "Usage: %s [-rx]\n", argv0);
79 threadexitsall("usage");
80 }
81
82 if(initdraw(0, nil, "colors") < 0)
83 sysfatal("initdraw failed: %r");
84
85 mousectl = initmouse(nil, display->image);
86 if(mousectl == nil)
87 sysfatal("initmouse: %r");
88
89 keyboardctl = initkeyboard(nil);
90 if(keyboardctl == nil)
91 sysfatal("initkeyboard: %r");
92
93 for(i=0; i<256; i++){
94 if(ramp){
95 if(screen->chan == CMAP8){
96 /* dither the fine grey */
97 j = i-(i%17);
98 dark = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (grey(j)<<8)+0xFF);
99 color[i] = allocimage(display, Rect(0,0,4,4), screen->chan, 1, (grey(j+17)<<8)+0xFF);
100 for(j=0; j<16; j++){
101 k = j%4;
102 l = j/4;
103 if(dither[j] > (i%17))
104 draw(color[i], Rect(k, l, k+1, l+1), dark, nil, ZP);
105 }
106 freeimage(dark);
107 }else
108 color[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (grey(i)<<8)+0xFF);
109 }else
110 color[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (cmap2rgb(i)<<8)+0xFF);
111 if(color[i] == nil)
112 sysfatal("can't allocate image: %r");
113 }
114
115 threadcreate(mousethread, nil, STACK);
116 threadcreate(keyboardthread, nil, STACK);
117 threadcreate(resizethread, nil, STACK);
118 }
119
120 void
121 keyboardthread(void *v)
122 {
123 Rune r;
124
125 USED(v);
126
127 while(recv(keyboardctl->c, &r) >= 0)
128 ;
129 }
130
131 char *buttons[] =
132 {
133 "exit",
134 0
135 };
136
137 Menu menu =
138 {
139 buttons
140 };
141
142 void
143 mousethread(void *v)
144 {
145 Point p;
146 Mouse m;
147 int i, n, prev;
148 char buf[100];
149 ulong rgb;
150
151 prev = -1;
152 while(readmouse(mousectl) >= 0){
153 m = mousectl->m;
154 switch(m.buttons){
155 case 1:
156 while(m.buttons){
157 if(screen->depth > 8)
158 n = 256;
159 else
160 n = 1<<screen->depth;
161 for(i=0; i!=n; i++)
162 if(i!=prev && ptinrect(m.xy, crect[i])){
163 if(ramp)
164 rgb = grey(i);
165 else
166 rgb = cmap2rgb(i);
167 sprint(buf, fmt,
168 i,
169 (rgb>>16)&0xFF,
170 (rgb>>8)&0xFF,
171 rgb&0xFF,
172 (rgb<<8) | 0xFF);
173 p = addpt(screen->r.min, Pt(2,2));
174 draw(screen, Rpt(p, addpt(p, stringsize(font, buf))), display->white, nil, p);
175 string(screen, p, display->black, ZP, font, buf);
176 prev=i;
177 break;
178 }
179 readmouse(mousectl);
180 m = mousectl->m;
181 }
182 break;
183
184 case 4:
185 switch(menuhit(3, mousectl, &menu, nil)){
186 case 0:
187 threadexitsall(0);
188 }
189 }
190 }
191 }
192
193 void
194 eresized(int new)
195 {
196 int x, y, i, n, nx, ny;
197 Rectangle r, b;
198
199 if(new && getwindow(display, Refnone) < 0){
200 fprint(2, "colors: can't reattach to window: %r\n");
201 threadexitsall("resized");
202 }
203 if(screen->depth > 8){
204 n = 256;
205 nx = 16;
206 }else{
207 n = 1<<screen->depth;
208 nx = 1<<(screen->depth/2);
209 }
210
211 ny = n/nx;
212 draw(screen, screen->r, display->white, nil, ZP);
213 r = insetrect(screen->r, 5);
214 r.min.y+=20;
215 b.max.y=r.min.y;
216 for(i=n-1, y=0; y!=ny; y++){
217 b.min.y=b.max.y;
218 b.max.y=r.min.y+(r.max.y-r.min.y)*(y+1)/ny;
219 b.max.x=r.min.x;
220 for(x=0; x!=nx; x++, --i){
221 b.min.x=b.max.x;
222 b.max.x=r.min.x+(r.max.x-r.min.x)*(x+1)/nx;
223 crect[i]=insetrect(b, 1);
224 draw(screen, crect[i], color[i], nil, ZP);
225 }
226 }
227 flushimage(display, 1);
228 }
229
230 void
231 resizethread(void *v)
232 {
233 ulong x;
234
235 USED(v);
236
237 eresized(0);
238 while(recv(mousectl->resizec, &x) >= 0)
239 eresized(1);
240 }