shithub: misc

ref: d226fadbe974f0e813d3f3ef5b20b2cabced437a
dir: /cpick.c/

View raw version
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <draw.h>
#include <keyboard.h>
#include <mouse.h>

/* there should really be a color picker in paint(1) instead */

Keyboardctl *kc;
Mousectl *mc;
Image *pic, *boxc;
Point pan;
Rectangle box;

void
putcol(Point m)
{
	char s[32];
	uchar buf[4];
	u32int v;
	Point p;

	p = addpt(screen->r.min, pan);
	unloadimage(pic, rectsubpt(Rpt(m, Pt(m.x+1, m.y+1)), p), buf, sizeof buf);
	loadimage(boxc, boxc->r, buf, sizeof buf);
	draw(screen, rectaddpt(box, p), boxc, nil, ZP);
	v = buf[0] << 16 | buf[1] << 8 | buf[2];
	snprint(s, sizeof s, "%#08ux", v);
	string(screen, addpt(box.min, p), display->black, ZP, font, s);
	flushimage(display, 1);
}

void
redraw(void)
{
	draw(screen, rectaddpt(pic->r, addpt(screen->r.min, pan)), pic, nil, ZP);
	flushimage(display, 1);
}

Image *
iconv(Image *i)
{
	Image *ni;

	if(i->chan == XBGR32)
		return i;
	if((ni = allocimage(display, i->r, XBGR32, 0, DNofill)) == nil)
		sysfatal("allocimage: %r");
	draw(ni, ni->r, i, nil, ZP);
	freeimage(i);
	return ni;
}

void
threadmain(int, char **)
{
	int fd;
	Mouse om;
	Rune r;

	if(initdraw(nil, nil, "cpick") < 0)
		sysfatal("initdraw: %r");
	if((fd = open("/dev/screen", OREAD)) < 0)
		sysfatal("open: %r");
	if((pic = readimage(display, fd, 0)) == nil)
		sysfatal("readimage: %r");
	close(fd);
	pic = iconv(pic);
	box = screen->r;
	if((boxc = allocimage(display, Rect(0,0,1,1), pic->chan, 1, DNofill)) == nil)
		sysfatal("allocimage: %r");
	redraw();
	if((kc = initkeyboard(nil)) == nil)
		sysfatal("initkeyboard: %r");
	if((mc = initmouse(nil, _screen->display->image)) == nil)
		sysfatal("initmouse: %r");
	om.xy = ZP;
	Alt a[] = {
		{mc->resizec, nil, CHANRCV},
		{mc->c, &mc->Mouse, CHANRCV},
		{kc->c, &r, CHANRCV},
		{nil, nil, CHANEND}
	};
	for(;;){
		switch(alt(a)){
		case 0:
			if(getwindow(display, Refnone) < 0)
				sysfatal("getwindow: %r");
			om = mc->Mouse;
			redraw();
			break;
		case 1:
			if(eqpt(om.xy, ZP))
				om = mc->Mouse;
			if((mc->buttons & 4) == 4){
				pan.x += mc->xy.x - om.xy.x;
				pan.y += mc->xy.y - om.xy.y;
				redraw();
			}else
				putcol(mc->xy);
			om = mc->Mouse;
			break;
		case 2:
			switch(r){
			case Kdel: case 'q': threadexitsall(nil);
			}
			break;
		default:
			threadexitsall("alt: %r");
		}
	}
}