ref: fbd2be563dc2460c707017485ca43ce42a5b946d
parent: 47820fc9d475fec74b9dd617241216d686b63316
author: phil9 <telephil9@gmail.com>
date: Wed Nov 24 16:35:27 EST 2021
implement image rotation image rotation options are available via menu2. It basically pipes the image to rotate(1).
--- a/view.c
+++ b/view.c
@@ -26,16 +26,33 @@
enum
{
+ Mhflip,
+ Mvflip,
+ Mrotleft,
+ Mrotright,
+};
+char *menu2str[] =
+{
+ "flip horiz.",
+ "flip vert.",
+ "rotate left",
+ "rotate right",
+ nil,
+};
+Menu menu2 = { menu2str };
+
+enum
+{
Mopen,
Mexit,
};
-char *menu2str[] =
+char *menu3str[] =
{
"open",
"exit",
nil,
};
-Menu menu2 = { menu2str };
+Menu menu3 = { menu3str };
void redraw(void);
@@ -219,12 +236,96 @@
redraw();
}
+Image*
+rotate(int op)
+{
+ static char *oparg[] = {
+ [Mhflip] = "-l",
+ [Mvflip] = "-u",
+ [Mrotleft] = "-r 270",
+ [Mrotright] = "-r 90",
+ };
+ Image *i;
+ int ifd[2], ofd[2];
+ char *argv[3] = { "rotate", oparg[op], nil };
+
+ if(pipe(ifd) < 0)
+ return nil;
+ if(pipe(ofd) < 0){
+ close(ifd[0]);
+ close(ifd[1]);
+ return nil;
+ }
+ switch(rfork(RFFDG|RFPROC|RFNOWAIT)){
+ case -1:
+ close(ifd[0]);
+ close(ifd[1]);
+ close(ofd[0]);
+ close(ofd[1]);
+ return nil;
+ case 0:
+ dup(ifd[1], 0);
+ dup(ofd[1], 1);
+ close(ifd[1]);
+ close(ifd[0]);
+ close(ofd[1]);
+ close(ofd[0]);
+ exec("/bin/rotate", argv);
+ _exits("exec");
+ }
+ if(writeimage(ifd[0], img, 1) < 0){
+ i = nil;
+ goto End;
+ }
+ i = readimage(display, ofd[0], 1);
+End:
+ close(ifd[0]);
+ close(ifd[1]);
+ close(ofd[0]);
+ close(ofd[1]);
+ return i;
+}
+
void
+menu2hit(void)
+{
+ Image *i;
+ int n;
+
+ n = menuhit(2, mctl, &menu2, nil);
+ if(n >= 0){
+ i = rotate(n);
+ freeimage(img);
+ img = i;
+ pos = subpt(ZP, img->r.min);
+ redraw();
+ }
+}
+
+void
+menu3hit(void)
+{
+ char buf[255];
+ int n;
+
+ n = menuhit(3, mctl, &menu3, nil);
+ switch(n){
+ case Mopen:
+ if(enter("open:", buf, sizeof buf, mctl, kctl, nil) > 0){
+ if(loadfromfile(buf) < 0)
+ fprint(2, "cannot open file '%s': %r\n", buf);
+ }
+ break;
+ case Mexit:
+ threadexitsall(nil);
+ break;
+ }
+}
+
+void
evtmouse(Mouse m)
{
Point o;
- int n;
- char buf[255] = {0};
if(m.buttons == 1){
for(;;){
@@ -236,19 +337,10 @@
pan(subpt(mctl->xy, o));
}
}else if(m.buttons == 2){
- n = menuhit(2, mctl, &menu2, nil);
- switch(n){
- case Mopen:
- if(enter("open:", buf, sizeof buf, mctl, kctl, nil) > 0){
- if(loadfromfile(buf) < 0)
- fprint(2, "cannot open file '%s': %r\n", buf);
- }
- break;
- case Mexit:
- threadexitsall(nil);
- break;
- }
- }
+ menu2hit();
+ }else if(m.buttons == 4){
+ menu3hit();
+ }
}
void