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 }