shithub: drawfs

ref: 798897c28e191cd4c2513afb658fa196b3fbb95c
dir: /drawmgr/drawmgr.c/

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

void
usage(void)
{
	fprint(2, "usage: %s\n", argv0);
	exits("usage");
}

enum {
	Drefresh,
};

typedef struct Drawcmd Drawcmd;
struct Drawcmd {
	int cmd;
};

int drawdispfd;
int drawrefrfd;
int drawctlfd;
int mouseinfd;

void
dorefresh(int fd)
{
	Image *t;
	
	seek(fd, 0, 0);
	t = readimage(display, fd, 0);
	if (!t) {
		fprint(2, "readimage: %r\n");
		return;
	}
	fprint(2, "img: %R\n", t->r);
	draw(screen, rectaddpt(t->r, screen->r.min), t, nil, ZP);
	freeimage(t);
}

void
refreshimage(int full)
{
	fprint(2, "refreshimage\n");
	
	if (full) {
		if (drawdispfd < 0)
			drawdispfd = open("/mnt/drawcmd/display", OREAD);
		if (drawdispfd < 0)
			sysfatal("drawfs: display: %r");
		dorefresh(drawdispfd);
	} else {
		if (drawrefrfd < 0)
			drawrefrfd = open("/mnt/drawcmd/refresh", OREAD);
		if (drawrefrfd < 0)
			sysfatal("drawfs: refresh: %r");
		dorefresh(drawrefrfd);
	}
}

void
resized(int new)
{
	Point size;
	uchar buf[1+4+4];
	
	if (new && getwindow(display, Refnone) < 0)
		sysfatal("can't reattach to window: %r");
	
	draw(screen, screen->r, display->white, nil, ZP);
	
	size.x = Dx(screen->r);
	size.y = Dy(screen->r);
	
	// TODO: filesystem needs to properly hook up the new image in resize.
	// TODO: see: ../drawfs/fs.c:/^resizescreen
	// TODO: then this can be re-enabled
	/*
	buf[0] = 'r';
	BPLONG(buf+1, size.x);
	BPLONG(buf+5, size.y);
	write(drawctlfd, buf, 1+4+4);
	*/
	
	fprint(2, "resize %P\n", size);
	
	refreshimage(1);
}

void
initdrawfs(char *name)
{
	char file[256];
	int drawfd;
	
	if (strlen(name) + strlen("/srv/drawfs..cmd") + 2 > sizeof(file))
		sysfatal("drawfs: name too long: %s", name);
	
	snprint(file, sizeof file, "/srv/drawfs.%s.cmd", name);
	drawfd = open(file, ORDWR);
	if (drawfd < 0)
		sysfatal("drawfs: %r");
	if (mount(drawfd, -1, "/mnt/drawcmd", MREPL, "") < 0)
		sysfatal("mount drawfs: %r");
	
	drawctlfd = open("/mnt/drawcmd/ctl", ORDWR);
	if (drawctlfd < 0)
		sysfatal("drawfs: ctl: %r");
	
	drawdispfd = -1;
}

void
initmousefs(char *name)
{
	char file[256];
	int fd;
	
	if (strlen(name) + strlen("/srv/mousefs..cmd") + 2 > sizeof(file))
		sysfatal("mousefs: name too long: %s", name);
	
	snprint(file, sizeof file, "/srv/mousefs.%s.cmd", name);
	fd = open(file, ORDWR);
	if (fd < 0)
		sysfatal("mousefs: %r");
	if (mount(fd, -1, "/mnt/mousefs", MREPL, "") < 0)
		sysfatal("mount mousefs: %r");
	
	mouseinfd = open("/mnt/mousefs/mouse", OWRITE);
	if (mouseinfd < 0)
		sysfatal("mousefs: mouse: %r");
}

void
drawreadproc(void *arg)
{
	char buf[512];
	int n;
	Channel *c;
	Drawcmd cmd;
	
	c = arg;
	for (;;) {
		if ((n = read(drawctlfd, buf, sizeof(buf) - 1)) <= 0)
			sysfatal("drawreadproc eof: %r");
		buf[n] = 0;
		switch (buf[0]) {
		case 'r':
			cmd.cmd = Drefresh;
			break;
		}
		send(c, &cmd);
	}
}

void
initdrawprocs(Alt *a)
{
	a->c = chancreate(sizeof(Drawcmd), 0);
	proccreate(drawreadproc, a->c, 2048);
}

void
mouseproc(void *arg)
{
	char m[50];
	Point p;
	int mfd;
	Channel *c;
	
	c = arg;
	mfd = open("/dev/mouse", OREAD);
	if (mfd < 0)
		sysfatal("open /dev/mouse: %r");
	for (;;) {
		if (read(mfd, m, 49) != 49)
			sysfatal("mouse eof");
		p.x = atoi(m+1);
		p.y = atoi(m+1+12);
		p.x -= screen->r.min.x;
		p.y -= screen->r.min.y;
		snprint(m+1, 11, "%11d %11d", p.x, p.y);
		send(c, m);
	}
}

void
initmouseprocs(Alt *a)
{
	a->c = chancreate(sizeof(char)*50, 0);
	proccreate(mouseproc, a->c, 2048);
}

void
handledrawcmd(Drawcmd *d)
{
	switch (d->cmd) {
	case Drefresh:
		refreshimage(0);
		break;
	}
}

void
threadmain(int argc, char **argv)
{
	char mdata[50];
	Drawcmd dcmd;
	
	Alt a[] = {
		{ nil, mdata, CHANRCV },
		{ nil, &dcmd, CHANRCV },
		{ nil, nil, CHANEND },
	};
	
	char *name = nil;
	
	ARGBEGIN{
	case 'n':
		name = EARGF(usage());
		break;
	default:
		usage();
		break;
	}ARGEND;
	
	if (!name || !name[0])
		usage();
	
	rfork(RFNAMEG);
	
	initmousefs(name);
	initdrawfs(name);
	
	if (initdraw(nil, nil, "drawmgr") < 0)
		sysfatal("initdraw: %r");
	
	initmouseprocs(&a[0]);
	initdrawprocs(&a[1]);
	
	resized(0);
	
	for (;;) {
		switch (alt(a)) {
		case 0: /* mouse event */
			if (mdata[0] == 'r') {
				fprint(2, "resize\n");
				resized(1);
				break;
			}
			seek(mouseinfd, 0, 0);
			if (write(mouseinfd, mdata, 49) != 49)
				sysfatal("write mousein: %r");
			break;
		case 1: /* draw ctl event */
			handledrawcmd(&dcmd);
			break;
		}
	}
}