ref: b5bb94de9a129d9a063320402cc6cfe9c02f12ed
author: sirjofri <sirjofri@sirjofri.de>
date: Fri Dec 11 16:44:42 EST 2020
adds files this adds mkfile and plumbto.c source code. The project works already, you need the channel in your plumb rules echo plumb to chanselect >> /mnt/plumb/rules the messages need destination to this channel, as well as the attribute: channels=chan1,chan2,chan3 Whenever a message arrives there, the window pops up and you can click the correct destination channel (these are buttons). The message is altered (the channels attribute is removed) and delivered.
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,6 @@
+</$objtype/mkfile
+
+TARG=plumbto
+OFILES=plumbto.$O
+
+</sys/src/cmd/mkone
--- /dev/null
+++ b/plumbto.c
@@ -1,0 +1,157 @@
+#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");
+ }
+ }
+}