Plan 9 from Bell Labs’s /usr/web/sources/contrib/fgb/cmd/front.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include <thread.h>
#include <draw.h>
#include <mouse.h>
#include <keyboard.h>
#include <control.h>
#include <bio.h>
#include <ctype.h>

#define	STACK	32*1024

typedef struct
{
	char		*cmd;
	int		p[2];		/* p[1] is write to program; p[0] set to prog fd 0*/
	int		q[2];		/* q[0] is read from program; q[1] set to prog fd 1 */
	Channel	*sync;	/* chan(ulong) */
}Exec;


Controlset *cs;
int ctldeletequits = 1;
Channel *cread;
Channel *cwrite;
Channel *cexit;

char *colornames[3] = 
{
	"white",
	"black",
	"red"
};

char *label = "front";

void
execproc(void *v)
{
	Channel *sync;
	Exec *e;
	int p[2], q[2];
	char *cmd;

	threadsetname("execproc");
	e = v;
	p[0] = e->p[0];
	p[1] = e->p[1];
	q[0] = e->q[0];
	q[1] = e->q[1];
	cmd = e->cmd;
	sync = e->sync;
	rfork(RFFDG);
	free(e);
	dup(p[0], 0);
	close(p[0]);
	close(p[1]);
	if(q[0]){
		dup(q[1], 1);
		close(q[0]);
		close(q[1]);
	}
	if(0)
		close(2);
	procexecl(sync, "/bin/rc", "rc", "-c", cmd, 0);
	sysfatal("can't exec");
}

void
readproc(void *v)
{
	Biobuf *b;
	int i, n;
	char *s;

	b = v;
	n = 0;
	for(;;){
		if((s=Brdline(b, '\n')) == nil)	
			sendul(cexit, 0);
		for(i=0; i<Blinelen(b)-1; i++)
			if(isspace(s[i]))
				s[i] = ' ';
		s[i] = '\0';
		chanprint(cs->ctl, "tarea add %q", s);
		chanprint(cs->ctl, "tarea scroll 1");
		chanprint(cs->ctl, "slider  max %d", ++n);
	}
}

void
writeproc(void *v)
{
	int fd;
	char *s;

	fd = (int)v;
	for(;;){
		s = recvp(cwrite);
		fprint(fd, "%s\n", s+6);
		chanprint(cs->ctl, "entry value %q", "");
		free(s);
	}
}

void
backend(char *cmd)
{
	Exec *e;
	Channel *sync;
	Biobuf bi;
	int p[2], q[2];

	if(pipe(p)<0 || pipe(q)<0)
		sysfatal("can't create pipe: %r");

	sync = chancreate(sizeof(ulong), 0);
	if(sync == nil)
		sysfatal("can't create channel: %r");

	e = malloc(sizeof(Exec));
	if(e == nil)
		sysfatal("can't malloc: %r");

	e->p[0] = p[0];
	e->p[1] = p[1];
	e->q[0] = q[0];
	e->q[1] = q[1];
	e->cmd = cmd;
	e->sync = sync;
	proccreate(execproc, e, STACK);
	recvul(sync);
	chanfree(sync);
	close(p[0]);
	close(q[1]);
	Binit(&bi, q[0], OREAD);
	proccreate(readproc, &bi, STACK);
	proccreate(writeproc, (void *)p[1], STACK);
}

void
resizecontrolset(Controlset*)
{
	Rectangle r, r1, r2, r3;


	if(getwindow(display, Refnone) < 0)
		sysfatal("resize failed: %r");
	r = insetrect(screen->r, 10);
	r1 = r;
	r1.min.x += stringwidth(font, "0") +20;
	r1.max.y -= 1+font->height+1+10;
	r2 = r;
	r2.min.y = r1.max.y+10;
	chanprint(cs->ctl, "tarea rect %R \ntarea show", r1);
	chanprint(cs->ctl, "entry rect %R \nentry show", r2);
	r3 = r;
	r3.max.x = r1.min.x-10;
	r3.max.y = r1.max.y;
	chanprint(cs->ctl, "slider rect %R \nslider show", r3);
}

int	mainstacksize = STACK;

void
threadmain(int argc, char *argv[])
{
	Control *entry, *tarea, *slider;
	int i;

	ARGBEGIN{
	case 'c':
		for(i=0; i<3; i++){
			colornames[i] = ARGF();
			if(colornames[i] == nil)
				goto Usage;
		}
		break;
	case 'l':
		label = ARGF();
		if(label == nil)
			goto Usage;
		break;
	default:
Usage:
		fprint(2, "Usage: front name: %d\n", argc);
		exits("usage");
	}ARGEND

	if(argc != 1)
		goto Usage;

	if(initdraw(0, 0, label) < 0)
		sysfatal("can't open display");

	initcontrols();
	cs = newcontrolset(screen, nil, nil, nil);
	cs->clicktotype = 1;	

	slider = createslider(cs, "slider");
	chanprint(cs->ctl, "slider border 1");
	chanprint(cs->ctl, "slider border 1");
	chanprint(cs->ctl, "slider image %s", colornames[0]);
	chanprint(cs->ctl, "slider bordercolor %s", colornames[1]);
	chanprint(cs->ctl, "slider indicatorcolor %s", colornames[2]);
	chanprint(cs->ctl, "slider format %q", "%q: tarea topline %d");
	chanprint(cs->ctl, "slider absolute 0");


	entry = createentry(cs, "entry");
	chanprint(cs->ctl, "entry border 1");
	chanprint(cs->ctl, "entry format %q", "%q:%s");

	tarea = createtext(cs, "tarea");
	chanprint(cs->ctl, "tarea border 1");

	cread = chancreate(sizeof(char *), 0);
	cwrite = chancreate(sizeof(char *), 0);
	cexit = chancreate(sizeof(int), 0);
	if(cread==nil || cwrite==nil || cexit==nil)
		sysfatal("can't create channels. %r");

	controlwire(entry, "event", cwrite);
	controlwire(tarea, "event", cs->ctl);
	controlwire(slider, "event", cs->ctl);
	activate(slider);
	activate(entry);
	activate(tarea);

	resizecontrolset(cs);
	backend(argv[0]);
	recvul(cexit);
	threadexitsall(nil);
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.