blob: caac0be66e713101ac5449cfa6e1b09d344173ab [file] [log] [blame]
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <keyboard.h>
#include <mouse.h>
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
};
extern int chattydrawclient;
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 'D':
chattydrawclient = 1;
break;
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);
threadexitsall("usage");
}
if(initdraw(0, 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<<screen->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:
threadexitsall(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");
threadexitsall("resized");
}
if(screen->depth > 8){
n = 256;
nx = 16;
}else{
n = 1<<screen->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);
}