URI: 
       ttcolors.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       ttcolors.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 }