tcolors.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 }