shithub: plumbto

ref: cf51a63bb605f03b5a3bd528a2a1725e42c3f7d0
dir: plumbto/plumbto.c

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

Controlset *cs;
int ctldeletequits = 1;

Control *items[] = {
	nil, /* pmhead */
	nil,
	nil, nil, nil, nil, nil,
	nil, nil, nil,
};
int itemsize = 1;
int maxitems = 10;

void
resizecontrolset(Controlset*)
{
	int i;
	Rectangle r;
	if (getwindow(display, Refnone) < 0)
		sysfatal("resize failed: %r");
	r = insetrect(screen->r, 10);
	for (i = 0; items[i]; i++){
		r = insetrect(screen->r, 10);
		r.min.y = r.min.y +  i   *(1+font->height+1);
		r.max.y = r.min.y +       (1+font->height+1);
		chanprint(cs->ctl, "%s rect %R\n%s show", items[i]->name, r, items[i]->name);
	}
}

int pfd, psfd;
Plumbmsg *pm;
char *channels;

void
plumblisten(void *arg)
{
	while ((pm = plumbrecv(pfd)) != nil){
		channels = plumblookup(pm->attr, "channels");
		if (channels != nil && strcmp(channels, "") != 0)
			send((Channel*)arg, 0);
	}
}

void
cleanup(void)
{
	int i;
	for (i = 1; items[i]; i++){
		closecontrol(items[i]);
		items[i] = nil;
	}
	resizecontrolset(cs);
}

void
handleplumb(Channel *c)
{
	char *args[10]; // maxitems-1+1
	int n, i;

	cleanup();

	n = getfields(channels, args, 10, 1, ",");
	for (i = 0; i < n; i++){
		items[i+1] = createtextbutton(cs, args[i]);
		activate(items[i+1]);
		chanprint(cs->ctl, "%q text %q", args[i], args[i]);
		controlwire(items[i+1], "event", c);
		itemsize++;
	}
	resizecontrolset(cs);
}

void
handleevent(char *c)
{
	char *args[10];
	int n;
	
	gettokens(c, args, 10, " \t:");
	
	if (atoi(args[2]) == 1){
		pm->attr = plumbdelattr(pm->attr, "channels");
		pm->dst = args[0];
		n = plumbsend(psfd, pm);
		if (!n)
			fprint(2, "plumbsend failed: %r\n");
	}
	cleanup();
}

void
threadmain(int argc, char **argv)
{
	USED(argc, argv);
	int i;
	int wctlfd;
	char *chanval;
	Alt a[] = {
		{nil, &i, CHANRCV},
		{nil, &chanval, CHANRCV},
		{nil, nil, CHANEND},
	};
	
	pfd = plumbopen("chanselect", OREAD);
	if (!pfd)
		sysfatal("cannot open plumb channel: %r");
	psfd = plumbopen("send", OWRITE);
	if (!psfd)
		sysfatal("cannot open plumb send: %r");
	
	wctlfd = open("/dev/wctl", OWRITE);
	if (wctlfd)
		fprint(wctlfd, "hide\n");
	
	initdraw(0, 0, "plumbto!");
	initcontrols();
	
	a[0].c = chancreate(sizeof(int), 0);
	proccreate(plumblisten, a[0].c, 2048);
	
	cs = newcontrolset(screen, nil, nil, nil);
	cs->clicktotype = 1;
	
	items[0] = createlabel(cs, "pmhead");
	chanprint(cs->ctl, "pmhead value %q", "no message");
	
	a[1].c = chancreate(sizeof(char*), 0);
	
	resizecontrolset(cs);
	for (;;){
		switch (alt(a)){
		case 0: /* plumb event */
			chanprint(cs->ctl, "pmhead value %q", pm->wdir);
			handleplumb(a[1].c);
			if (wctlfd)
				fprint(wctlfd, "unhide\n");
			break;
		case 1: /* control event */
			handleevent(chanval);
		//	plumbfree(pm);
			if (wctlfd)
				fprint(wctlfd, "hide\n");
			break;
		default:
			sysfatal("can't happen");
		}
	}
}