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; } } }