plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

colors.c (3206B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <draw.h>
      4 #include <event.h>
      5 
      6 int nbit, npix;
      7 Image *pixel;
      8 Rectangle crect[256];
      9 
     10 Image *color[256];
     11 
     12 void
     13 eresized(int new)
     14 {
     15 	int x, y, i, n, nx, ny;
     16 	Rectangle r, b;
     17 
     18 	if(new && getwindow(display, Refnone) < 0){
     19 		fprint(2, "colors: can't reattach to window: %r\n");
     20 		exits("resized");
     21 	}
     22 	if(screen->depth > 8){
     23 		n = 256;
     24 		nx = 16;
     25 	}else{
     26 		n = 1<<screen->depth;
     27 		nx = 1<<(screen->depth/2);
     28 	}
     29 
     30 	ny = n/nx;
     31 	draw(screen, screen->r, display->white, nil, ZP);
     32 	r = insetrect(screen->r, 5);
     33 	r.min.y+=20;
     34 	b.max.y=r.min.y;
     35 	for(i=n-1, y=0; y!=ny; y++){
     36 		b.min.y=b.max.y;
     37 		b.max.y=r.min.y+(r.max.y-r.min.y)*(y+1)/ny;
     38 		b.max.x=r.min.x;
     39 		for(x=0; x!=nx; x++, --i){
     40 			b.min.x=b.max.x;
     41 			b.max.x=r.min.x+(r.max.x-r.min.x)*(x+1)/nx;
     42 			crect[i]=insetrect(b, 1);
     43 			draw(screen, crect[i], color[i], nil, ZP);
     44 		}
     45 	}
     46 	flushimage(display, 1);
     47 }
     48 
     49 char *buttons[] =
     50 {
     51 	"exit",
     52 	0
     53 };
     54 
     55 ulong
     56 grey(int i)
     57 {
     58 	if(i < 0)
     59 		return grey(0);
     60 	if(i > 255)
     61 		return grey(255);
     62 	return (i<<16)+(i<<8)+i;
     63 }
     64 
     65 Menu menu =
     66 {
     67 	buttons
     68 };
     69 
     70 int
     71 dither[16] =  {
     72 	0, 8, 2, 10,
     73 	12, 4, 14, 6,
     74 	3, 11, 1, 9,
     75 	15, 7, 13, 5
     76 };
     77 
     78 void
     79 main(int argc, char *argv[])
     80 {
     81 	Point p;
     82 	Mouse m;
     83 	int i, j, k, l, n, ramp, prev;
     84 	char buf[100];
     85 	char *fmt;
     86 	Image *dark;
     87 	ulong rgb;
     88 
     89 	ramp = 0;
     90 
     91 	fmt = "index %3d r %3lud g %3lud b %3lud 0x%.8luX        ";
     92 	ARGBEGIN{
     93 	default:
     94 		goto Usage;
     95 	case 'x':
     96 		fmt = "index %2luX r %3luX g %3luX b %3luX 0x%.8luX       ";
     97 		break;
     98 	case 'r':
     99 		ramp = 1;
    100 		break;
    101 	}ARGEND
    102 
    103 	if(argc){
    104 	Usage:
    105 		fprint(2, "Usage: %s [-rx]\n", argv0);
    106 		exits("usage");
    107 	}
    108 
    109 	if(initdraw(0, 0, "colors") < 0)
    110 		sysfatal("initdraw failed: %r");
    111 	einit(Emouse);
    112 
    113 	for(i=0; i<256; i++){
    114 		if(ramp){
    115 			if(screen->chan == CMAP8){
    116 				/* dither the fine grey */
    117 				j = i-(i%17);
    118 				dark = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (grey(j)<<8)+0xFF);
    119 				color[i] = allocimage(display, Rect(0,0,4,4), screen->chan, 1, (grey(j+17)<<8)+0xFF);
    120 				for(j=0; j<16; j++){
    121 					k = j%4;
    122 					l = j/4;
    123 					if(dither[j] > (i%17))
    124 						draw(color[i], Rect(k, l, k+1, l+1), dark, nil, ZP);
    125 				}
    126 				freeimage(dark);
    127 			}else
    128 				color[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (grey(i)<<8)+0xFF);
    129 		}else
    130 			color[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (cmap2rgb(i)<<8)+0xFF);
    131 		if(color[i] == nil)
    132 			sysfatal("can't allocate image: %r");
    133 	}
    134 	eresized(0);
    135 	prev = -1;
    136 	for(;;){
    137 flushimage(display, 1);
    138 		m = emouse();
    139 		switch(m.buttons){
    140 		case 1:
    141 			while(m.buttons){
    142 				if(screen->depth > 8)
    143 					n = 256;
    144 				else
    145 					n = 1<<screen->depth;
    146 				for(i=0; i!=n; i++)
    147 					if(i!=prev && ptinrect(m.xy, crect[i])){
    148 						if(ramp)
    149 							rgb = grey(i);
    150 						else
    151 							rgb = cmap2rgb(i);
    152 						sprint(buf, fmt,
    153 							i,
    154 							(rgb>>16)&0xFF,
    155 							(rgb>>8)&0xFF,
    156 							rgb&0xFF,
    157 							(rgb<<8) | 0xFF);
    158 						p = addpt(screen->r.min, Pt(2,2));
    159 						draw(screen, Rpt(p, addpt(p, stringsize(font, buf))), display->white, nil, p);
    160 						string(screen, p, display->black, ZP, font, buf);
    161 						prev=i;
    162 						break;
    163 					}
    164 				m = emouse();
    165 			}
    166 			break;
    167 
    168 		case 4:
    169 			switch(emenuhit(3, &m, &menu)){
    170 			case 0:
    171 				exits(0);
    172 			}
    173 		}
    174 	}
    175 }