ref: 0f3ef52fd7792c660587bc477668fea55aa8d947
parent: 58b3f96f98895e1352c12388cffdb7eed180a484
author: Sigrid <ftrvxmtrx@gmail.com>
date: Sat Jan 16 13:30:50 EST 2021
tweak: support showdata plumb action (thanks sirjofri)
--- a/sys/man/1/tweak
+++ b/sys/man/1/tweak
@@ -155,6 +155,16 @@
Quit
.IR tweak .
The program will complain once about modified but unwritten files.
+.PP
+.I Tweak
+listens to the
+.I plumber
+channel
+.B imageedit
+for filenames as well as image data. Plumbed image data is stored as files in
+.B /tmp
+and is automatically cleaned when exiting
+.IR tweak .
.SH SOURCE
.B /sys/src/cmd/tweak.c
.SH "SEE ALSO"
--- a/sys/src/cmd/tweak.c
+++ b/sys/src/cmd/tweak.c
@@ -3,8 +3,11 @@
#include <draw.h>
#include <cursor.h>
#include <event.h>
+#include <plumb.h>
#include <bio.h>
+#define Eplumb 128
+
typedef struct Thing Thing;
struct Thing
@@ -157,6 +160,8 @@
int but1val = 0;
int but2val = 255;
int invert = 0;
+int blockinput = 0;
+int tmpindex = 0;
Image *values[256];
Image *greyvalues[256];
uchar data[8192];
@@ -172,12 +177,60 @@
void tclose1(Thing*);
void
+flushevents(ulong keys)
+{
+ Event e;
+ if(keys == 0)
+ return;
+ while(ecanread(keys))
+ eread(keys, &e);
+}
+
+char*
+pshowdata(Plumbmsg *pm)
+{
+ int fd;
+ char *file;
+ file = smprint("/tmp/tweaktmp.%d.%d", getpid(), tmpindex++);
+ if(file == 0)
+ sysfatal("malloc failed: %r");
+ fd = create(file, OWRITE|OEXCL, 0600);
+ if(fd < 0){
+ free(file);
+ mesg("cannot create tmpfile.");
+ return nil;
+ }
+ if(write(fd, pm->data, pm->ndata) != pm->ndata){
+ mesg("error writing tmpfile: %r");
+ close(fd);
+ free(file);
+ return nil;
+ }
+ close(fd);
+ return file;
+}
+
+char*
+pfilename(Plumbmsg *pm)
+{
+ char *file;
+ if(pm->data[0] == '/')
+ file = smprint("%.*s", pm->ndata, pm->data);
+ else
+ file = smprint("%s/%.*s", pm->wdir, pm->ndata, pm->data);
+ return cleanname(file);
+}
+
+void
main(int argc, char *argv[])
{
int i;
Event e;
Thing *t;
+ Plumbmsg *pm;
+ char *s;
+ srand(time(0));
mag = Mag;
if(initdraw(error, 0, "tweak") < 0){
fprint(2, "tweak: initdraw failed: %r\n");
@@ -190,6 +243,7 @@
drawerror(display, "can't allocate image");
}
einit(Emouse|Ekeyboard);
+ eplumb(Eplumb, "imageedit");
eresized(0);
i = 1;
setjmp(err);
@@ -214,10 +268,42 @@
}
if(mouse.buttons & 4)
menu();
+ break;
+ case Eplumb:
+ pm = e.v;
+ if(pm->ndata == 0)
+ break;
+ s = plumblookup(pm->attr, "action");
+ if(s && strcmp(s, "showdata") == 0)
+ file = pshowdata(pm);
+ else
+ file = pfilename(pm);
+ if(!file){
+ mesg("invalid plumb data");
+ plumbfree(pm);
+ break;
+ }
+ plumbfree(pm);
+ t = tget(file);
+ if(t)
+ drawthing(t, 1);
+ flushimage(display, 1);
+ file = 0;
}
}
void
+cleantmpfiles(void)
+{
+ char *s;
+ for(tmpindex--; tmpindex >= 0; tmpindex--){
+ s = smprint("/tmp/tweaktmp.%d.%d", getpid(), tmpindex);
+ remove(s);
+ free(s);
+ }
+}
+
+void
error(Display*, char *s)
{
if(file)
@@ -226,6 +312,7 @@
mesg("/dev/bitblt error: %s", s);
if(err[0])
longjmp(err, 1);
+ cleantmpfiles();
exits(s);
}
@@ -531,6 +618,12 @@
nt->tr.max.y = nt->tr.min.y + nl;
nt->er.max.y = nt->tr.max.y + Border;
text(nt);
+
+ mesg("");
+ if(blockinput){
+ flushevents(Emouse|Ekeyboard);
+ blockinput = 0;
+ }
}
int
@@ -557,6 +650,9 @@
uchar buf[256];
char *data;
+ mesg("reading %s", file);
+ blockinput = 1;
+
buf[0] = '\0';
errstr((char*)buf, sizeof buf); /* flush pending error message */
memmove(oerr, err, sizeof err);
@@ -2041,6 +2137,7 @@
buttons(Down);
if(mouse.buttons == 4){
buttons(Up);
+ cleantmpfiles();
exits(0);
}
buttons(Up);