plan9port

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

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 }