#include <u.h>#include <libc.h>#include <bio.h>#include <draw.h>#include <keyboard.h>#include <mouse.h>#include <thread.h> Channel *wc;Image *i; typedef struct Rc Rc;struct Rc{ int fd[2]; char *cmd; uint nms;}; voidresize(Point p){ int fd; fd = open("/dev/wctl", OWRITE); if(fd >= 0){ fprint(fd, "resize -dx %d -dy %d", p.x+4*2, p.y+4*2); close(fd); }} voidresizeto(Point p){ Point s; s = (Point){Dx(screen->r), Dy(screen->r)}; if(eqpt(p, s)) return; resize(p);} voideresized(int new){ static int delaynew = 1; if(new && getwindow(display, Refnone) < 0) sysfatal("imgloop: can't reattach to window\n"); if(new) delaynew = 1; if(i == nil) return; if(delaynew){ resizeto((Point){Dx(i->r), Dy(i->r)}); delaynew = 0; }// drawop(screen, r, image, nil, image->r.min, S); draw(screen, screen->clipr, i, display->white, ZP); flushimage(display, 1);} voidrunrcproc(void *v){ int nfd; Rc *rc; rc = v; nfd = open("/dev/null", ORDWR); dup(nfd, 0); dup(rc->fd[1], 1); close(rc->fd[0]); close(nfd); procexecl(wc, "/bin/rc", "rc", "-c", rc->cmd, nil);} intrcproc(void *v){ Rc *rc; Image *ni, *oi; enum { Flags = RFFDG|RFPROC, }; rc = v; threadsetname("imgloop %s", rc->cmd); chancreate(sizeof(ulong), 1); for(;;){ if(pipe(rc->fd) == -1) sysfatal("pipe: %r"); if(procrfork(runrcproc, rc, 8*1024, Flags) == -1) return -1; close(rc->fd[1]); ni = readimage(display, rc->fd[0], 0); oi = i; i = ni; eresized(0); freeimage(oi); eresized(0); close(rc->fd[0]);// recvul(wc); /* eat pid */ sleep(rc->nms); }} voidresizedproc(void*){ char buf[128], *f[7]; int n, fd; threadsetname("resizeproc"); fd = open("/dev/wctl", OREAD); for(;;){ n = read(fd, buf, sizeof buf-1); if(n<4*12) sysfatal("bad wctl: %r"); buf[n] = 0; n = tokenize(buf, f, nelem(f)); if(n != 6) sysfatal("bad wctl: %d fields", n); if(strcmp(f[4], "current") == 0 && strcmp(f[5], "visible") == 0) eresized(1); }} voidmouseproc(void *){ void *v; Rune r; Alt alts[4]; Keyboardctl *k; Mousectl *m; Mouse mc; enum{Amouse, Akbd, Aresize, Aend}; m = initmouse("/dev/mouse", nil); k = initkeyboard("/dev/cons"); memset(alts, 0, sizeof alts); alts[Amouse].c = m->c; alts[Amouse].v = &mc; alts[Amouse].op = CHANRCV; alts[Akbd].c = k->c; alts[Akbd].v = &r; alts[Akbd].op = CHANRCV; alts[Aresize].c = m->resizec; alts[Aresize].v = &v; alts[Aresize].op = CHANRCV; alts[Aend].op = CHANEND; for(;;) switch(alt(alts)){ default: sysfatal("mouse!"); case Amouse: break; case Akbd: switch(r){ case 'q': case 0x7f: case 0x04: threadexitsall(""); } break; case Aresize: break; }} voidderror(Display*, char *s){ sysfatal("%s", s);} voidusage(void){ fprint(2, "usage: imgloop [-i framems] [-c cmd]\n"); threadexits("usage");} char*argstr(int argc, char **argv){ char *s, *p, *e; int i, len; len = 0; for(i = 0; i < argc; i++) len += strlen(argv[i])+1; s = malloc(len+1); e = s + len+1; p = s; for(i = 0; i < argc; i++) p = seprint(p, e, "%s ", argv[i]); seprint(p, e, "\n"); if(p == s) usage(); return s;} voidthreadmain(int argc, char **argv){ Rc rc; memset(&rc, 0, sizeof rc); rc.nms = 2*60*1000; rc.cmd = "radar -9"; ARGBEGIN{ default: usage(); case 'i': rc.nms = atoi(EARGF(usage())); break; case 'c': rc.cmd = argstr(argc-1, argv+1); goto done; }ARGENDdone: if(geninitdraw(nil, derror, "/lib/font/bit/cyberbit/mod14.font", "imgloop", nil, Refnone) == -1) sysfatal("imgloop: can't open display: %r"); eresized(0); proccreate(mouseproc, nil, 8192); proccreate(resizedproc, nil, 8192); rcproc(&rc); threadexits("");}
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <draw.h>
#include <keyboard.h>
#include <mouse.h>
#include <thread.h>
Channel *wc;
Image *i;
typedef struct Rc Rc;
struct Rc{
int fd[2];
char *cmd;
uint nms;
};
void
resize(Point p)
{
int fd;
fd = open("/dev/wctl", OWRITE);
if(fd >= 0){
fprint(fd, "resize -dx %d -dy %d", p.x+4*2, p.y+4*2);
close(fd);
}
}
void
resizeto(Point p)
{
Point s;
s = (Point){Dx(screen->r), Dy(screen->r)};
if(eqpt(p, s))
return;
resize(p);
}
void
eresized(int new)
{
static int delaynew = 1;
if(new && getwindow(display, Refnone) < 0)
sysfatal("imgloop: can't reattach to window\n");
if(new)
delaynew = 1;
if(i == nil)
return;
if(delaynew){
resizeto((Point){Dx(i->r), Dy(i->r)});
delaynew = 0;
}
// drawop(screen, r, image, nil, image->r.min, S);
draw(screen, screen->clipr, i, display->white, ZP);
flushimage(display, 1);
}
void
runrcproc(void *v)
{
int nfd;
Rc *rc;
rc = v;
nfd = open("/dev/null", ORDWR);
dup(nfd, 0);
dup(rc->fd[1], 1);
close(rc->fd[0]);
close(nfd);
procexecl(wc, "/bin/rc", "rc", "-c", rc->cmd, nil);
}
int
rcproc(void *v)
{
Rc *rc;
Image *ni, *oi;
enum { Flags = RFFDG|RFPROC, };
rc = v;
threadsetname("imgloop %s", rc->cmd);
chancreate(sizeof(ulong), 1);
for(;;){
if(pipe(rc->fd) == -1)
sysfatal("pipe: %r");
if(procrfork(runrcproc, rc, 8*1024, Flags) == -1)
return -1;
close(rc->fd[1]);
ni = readimage(display, rc->fd[0], 0);
oi = i;
i = ni;
eresized(0);
freeimage(oi);
eresized(0);
close(rc->fd[0]);
// recvul(wc); /* eat pid */
sleep(rc->nms);
}
}
void
resizedproc(void*)
{
char buf[128], *f[7];
int n, fd;
threadsetname("resizeproc");
fd = open("/dev/wctl", OREAD);
for(;;){
n = read(fd, buf, sizeof buf-1);
if(n<4*12)
sysfatal("bad wctl: %r");
buf[n] = 0;
n = tokenize(buf, f, nelem(f));
if(n != 6)
sysfatal("bad wctl: %d fields", n);
if(strcmp(f[4], "current") == 0
&& strcmp(f[5], "visible") == 0)
eresized(1);
}
}
void
mouseproc(void *)
{
void *v;
Rune r;
Alt alts[4];
Keyboardctl *k;
Mousectl *m;
Mouse mc;
enum{Amouse, Akbd, Aresize, Aend};
m = initmouse("/dev/mouse", nil);
k = initkeyboard("/dev/cons");
memset(alts, 0, sizeof alts);
alts[Amouse].c = m->c;
alts[Amouse].v = &mc;
alts[Amouse].op = CHANRCV;
alts[Akbd].c = k->c;
alts[Akbd].v = &r;
alts[Akbd].op = CHANRCV;
alts[Aresize].c = m->resizec;
alts[Aresize].v = &v;
alts[Aresize].op = CHANRCV;
alts[Aend].op = CHANEND;
for(;;)
switch(alt(alts)){
default:
sysfatal("mouse!");
case Amouse:
break;
case Akbd:
switch(r){
case 'q':
case 0x7f:
case 0x04:
threadexitsall("");
}
break;
case Aresize:
break;
}
}
void
derror(Display*, char *s)
{
sysfatal("%s", s);
}
void
usage(void)
{
fprint(2, "usage: imgloop [-i framems] [-c cmd]\n");
threadexits("usage");
}
char*
argstr(int argc, char **argv)
{
char *s, *p, *e;
int i, len;
len = 0;
for(i = 0; i < argc; i++)
len += strlen(argv[i])+1;
s = malloc(len+1);
e = s + len+1;
p = s;
for(i = 0; i < argc; i++)
p = seprint(p, e, "%s ", argv[i]);
seprint(p, e, "\n");
if(p == s)
usage();
return s;
}
void
threadmain(int argc, char **argv)
{
Rc rc;
memset(&rc, 0, sizeof rc);
rc.nms = 2*60*1000;
rc.cmd = "radar -9";
ARGBEGIN{
default:
usage();
case 'i':
rc.nms = atoi(EARGF(usage()));
break;
case 'c':
rc.cmd = argstr(argc-1, argv+1);
goto done;
}ARGEND
done:
if(geninitdraw(nil, derror, "/lib/font/bit/cyberbit/mod14.font", "imgloop", nil, Refnone) == -1)
sysfatal("imgloop: can't open display: %r");
eresized(0);
proccreate(mouseproc, nil, 8192);
proccreate(resizedproc, nil, 8192);
rcproc(&rc);
threadexits("");
}