From fd4655403059a7b5c042e3ba206b9f3f94b9f831 Mon Sep 17 00:00:00 2001 From: rsc Date: Mon, 27 Dec 2004 05:21:41 +0000 Subject: good test programs --- src/cmd/draw/tcolors.c | 230 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 src/cmd/draw/tcolors.c (limited to 'src/cmd/draw/tcolors.c') diff --git a/src/cmd/draw/tcolors.c b/src/cmd/draw/tcolors.c new file mode 100644 index 00000000..60f49e68 --- /dev/null +++ b/src/cmd/draw/tcolors.c @@ -0,0 +1,230 @@ +#include +#include +#include +#include +#include +#include + +enum +{ + STACK = 8192, +}; + +int nbit, npix; +Image *pixel; +Rectangle crect[256]; +Image *color[256]; +char *fmt; +int ramp; + +Mousectl *mousectl; +Keyboardctl *keyboardctl; + +void keyboardthread(void*); +void mousethread(void*); +void resizethread(void*); + +ulong +grey(int i) +{ + if(i < 0) + return grey(0); + if(i > 255) + return grey(255); + return (i<<16)+(i<<8)+i; +} + +int +dither[16] = { + 0, 8, 2, 10, + 12, 4, 14, 6, + 3, 11, 1, 9, + 15, 7, 13, 5 +}; + +void +threadmain(int argc, char *argv[]) +{ + int i, j, k, l; + Image *dark; + + 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"); + + mousectl = initmouse(nil, display->image); + if(mousectl == nil) + sysfatal("initmouse: %r"); + + keyboardctl = initkeyboard(nil); + if(keyboardctl == nil) + sysfatal("initkeyboard: %r"); + + 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"); + } + + threadcreate(mousethread, nil, STACK); + threadcreate(keyboardthread, nil, STACK); + threadcreate(resizethread, nil, STACK); +} + +void +keyboardthread(void *v) +{ + Rune r; + + USED(v); + + while(recv(keyboardctl->c, &r) >= 0) + ; +} + +char *buttons[] = +{ + "exit", + 0 +}; + +Menu menu = +{ + buttons +}; + +void +mousethread(void *v) +{ + Point p; + Mouse m; + int i, n, prev; + char buf[100]; + ulong rgb; + + prev = -1; + while(readmouse(mousectl) >= 0){ + m = mousectl->m; + switch(m.buttons){ + case 1: + while(m.buttons){ + if(screen->depth > 8) + n = 256; + else + n = 1<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; + } + readmouse(mousectl); + m = mousectl->m; + } + break; + + case 4: + switch(menuhit(3, mousectl, &menu, nil)){ + case 0: + exits(0); + } + } + } +} + +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<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); +} + +void +resizethread(void *v) +{ + ulong x; + + USED(v); + + eresized(0); + while(recv(mousectl->resizec, &x) >= 0) + eresized(1); +} + -- cgit v1.2.3