ref: b5bb94de9a129d9a063320402cc6cfe9c02f12ed
dir: /plumbto.c/
#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"); } } }