ref: cbe4b116989c0bfec49b9ae7a1d9a85ead6648ae
dir: /sys/src/cmd/colors.c/
#include <u.h> #include <libc.h> #include <draw.h> #include <event.h> int nbit, npix; Image *pixel; Rectangle crect[256]; Image *color[256]; void eresized(int new) { int x, y, i, n, nx, ny; Rectangle r, b; if(new && getwindow(display, Refnone) < 0){ fprint(2, "colors: can't reattach to window: %r\n"); exits("resized"); } if(screen->depth > 8){ n = 256; nx = 16; }else{ n = 1<<screen->depth; nx = 1<<(screen->depth/2); } ny = n/nx; draw(screen, screen->r, display->white, nil, ZP); r = insetrect(screen->r, 5); r.min.y+=20; b.max.y=r.min.y; for(i=n-1, y=0; y!=ny; y++){ b.min.y=b.max.y; b.max.y=r.min.y+(r.max.y-r.min.y)*(y+1)/ny; b.max.x=r.min.x; for(x=0; x!=nx; x++, --i){ b.min.x=b.max.x; b.max.x=r.min.x+(r.max.x-r.min.x)*(x+1)/nx; crect[i]=insetrect(b, 1); draw(screen, crect[i], color[i], nil, ZP); } } flushimage(display, 1); } char *buttons[] = { "exit", 0 }; ulong grey(int i) { if(i < 0) return grey(0); if(i > 255) return grey(255); return (i<<16)+(i<<8)+i; } Menu menu = { buttons }; int dither[16] = { 0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5 }; void main(int argc, char *argv[]) { Point p; Mouse m; int i, j, k, l, n, ramp, prev; char buf[100]; char *fmt; Image *dark; ulong rgb; ramp = 0; fmt = "index %3d r %3lud g %3lud b %3lud 0x%.8luX "; ARGBEGIN{ default: goto Usage; case 'x': fmt = "index %2luX r %3luX g %3luX b %3luX 0x%.8luX "; break; case 'r': ramp = 1; break; }ARGEND if(argc){ Usage: fprint(2, "usage: %s [-rx]\n", argv0); exits("usage"); } if(initdraw(nil, nil, "colors") < 0) sysfatal("initdraw failed: %r"); einit(Emouse); for(i=0; i<256; i++){ if(ramp){ if(screen->chan == CMAP8){ /* dither the fine grey */ j = i-(i%17); dark = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (grey(j)<<8)+0xFF); color[i] = allocimage(display, Rect(0,0,4,4), screen->chan, 1, (grey(j+17)<<8)+0xFF); for(j=0; j<16; j++){ k = j%4; l = j/4; if(dither[j] > (i%17)) draw(color[i], Rect(k, l, k+1, l+1), dark, nil, ZP); } freeimage(dark); }else color[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (grey(i)<<8)+0xFF); }else color[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (cmap2rgb(i)<<8)+0xFF); if(color[i] == nil) sysfatal("can't allocate image: %r"); } eresized(0); prev = -1; for(;;){ m = emouse(); switch(m.buttons){ case 1: while(m.buttons){ if(screen->depth > 8) n = 256; else n = 1<<screen->depth; for(i=0; i!=n; i++) if(i!=prev && ptinrect(m.xy, crect[i])){ if(ramp) rgb = grey(i); else rgb = cmap2rgb(i); sprint(buf, fmt, i, (rgb>>16)&0xFF, (rgb>>8)&0xFF, rgb&0xFF, (rgb<<8) | 0xFF); p = addpt(screen->r.min, Pt(2,2)); draw(screen, Rpt(p, addpt(p, stringsize(font, buf))), display->white, nil, p); string(screen, p, display->black, ZP, font, buf); prev=i; break; } m = emouse(); } break; case 4: switch(emenuhit(3, &m, &menu)){ case 0: exits(0); } } } }