ref: 798897c28e191cd4c2513afb658fa196b3fbb95c
dir: /drawmgr/drawmgr.c/
#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;
}
}
}