aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBert <ber.t@gmx.com>2011-03-01 18:49:02 +0100
committerBert <ber.t@gmx.com>2011-03-01 18:49:02 +0100
commitc05fd44bdda2934fa6f2f83b776038659f9d7d71 (patch)
tree9580d1edc2168c185a88943b430bef1d814077f7
parent955c39a5c5e3193e18c21abe87110651cc2472d2 (diff)
downloadnsxiv-c05fd44bdda2934fa6f2f83b776038659f9d7d71.tar.zst
Support for external commands like mogrify & jpegtran
-rw-r--r--commands.h24
-rw-r--r--image.c7
-rw-r--r--image.h2
-rw-r--r--main.c84
-rw-r--r--thumbs.c8
-rw-r--r--window.c2
6 files changed, 115 insertions, 12 deletions
diff --git a/commands.h b/commands.h
new file mode 100644
index 0000000..6fcd602
--- /dev/null
+++ b/commands.h
@@ -0,0 +1,24 @@
+#define FILENAME (const char*) 0x1
+
+typedef struct {
+ KeySym ksym;
+ const char **cmdline;
+ Bool reload;
+} command_t;
+
+static const char *cmdline_1[] = { "jpegtran", "-rotate", "270", "-copy", "all",
+ "-outfile", FILENAME, FILENAME, NULL };
+static const char *cmdline_2[] = { "jpegtran", "-rotate", "90", "-copy", "all",
+ "-outfile", FILENAME, FILENAME, NULL };
+static const char *cmdline_3[] = { "mogrify", "-rotate", "-90", FILENAME,
+ NULL };
+static const char *cmdline_4[] = { "mogrify", "-rotate", "+90", FILENAME,
+ NULL };
+
+static command_t commands[] = {
+ /* key command-line reload? */
+ { XK_a, cmdline_1, True },
+ { XK_s, cmdline_2, True },
+ { XK_A, cmdline_3, True },
+ { XK_S, cmdline_4, True },
+};
diff --git a/image.c b/image.c
index 5a69c20..c8fab6a 100644
--- a/image.c
+++ b/image.c
@@ -99,10 +99,13 @@ int img_load(img_t *img, const char *filename) {
return 1;
}
-void img_close(img_t *img) {
+void img_close(img_t *img, int decache) {
if (img && img->im) {
imlib_context_set_image(img->im);
- imlib_free_image();
+ if (decache)
+ imlib_free_image_and_decache();
+ else
+ imlib_free_image();
img->im = NULL;
}
}
diff --git a/image.h b/image.h
index 2a9e218..370345f 100644
--- a/image.h
+++ b/image.h
@@ -57,7 +57,7 @@ void img_free(img_t*);
int img_check(const char*);
int img_load(img_t*, const char*);
-void img_close(img_t*);
+void img_close(img_t*, int);
void img_render(img_t*, win_t*);
diff --git a/main.c b/main.c
index ec803f6..e3a1fa2 100644
--- a/main.c
+++ b/main.c
@@ -23,6 +23,8 @@
#include <sys/select.h>
#include <sys/stat.h>
#include <sys/time.h>
+#include <sys/wait.h>
+#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@@ -33,6 +35,7 @@
#include "thumbs.h"
#include "util.h"
#include "window.h"
+#include "commands.h"
typedef enum {
MODE_NORMAL = 0,
@@ -62,7 +65,7 @@ void cleanup() {
static int in = 0;
if (!in++) {
- img_close(&img);
+ img_close(&img, 0);
img_free(&img);
tns_free(&tns, &win);
win_close(&win);
@@ -73,7 +76,7 @@ int load_image(int new) {
struct stat fstats;
if (new >= 0 && new < filecnt) {
- img_close(&img);
+ img_close(&img, 0);
fileidx = new;
if (!stat(filenames[fileidx], &fstats))
filesize = fstats.st_size;
@@ -270,6 +273,60 @@ void read_dir_rec(const char *dirname) {
free(dirnames);
}
+int run_command(const char **cmdline, Bool reload) {
+ int argc, i;
+ const char **argv;
+ pid_t pid;
+ int error, ret, status;
+
+ if (!cmdline)
+ return 0;
+
+ argc = 1;
+ while (cmdline[argc-1])
+ ++argc;
+
+ if (argc < 2)
+ return 0;
+
+ argv = (const char**) s_malloc(argc * sizeof(const char*));
+ error = ret = 0;
+
+ for (i = 0; i < argc; ++i) {
+ if (cmdline[i] != FILENAME)
+ argv[i] = cmdline[i];
+ else
+ argv[i] = filenames[mode == MODE_NORMAL ? fileidx : tns.sel];
+ }
+
+ if ((pid = fork()) == 0) {
+ execvp(argv[0], (char **const) argv);
+ warn("could not exec %s", argv[0]);
+ exit(1);
+ } else if (pid < 0 && !options->quiet) {
+ warn("could not fork. command line was:");
+ error = 1;
+ } else if (reload) {
+ waitpid(pid, &status, 0);
+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+ ret = 1;
+ } else if (!options->quiet) {
+ warn("child exited with non-zero return value: %d. command line was:",
+ WEXITSTATUS(status));
+ error = 1;
+ }
+ }
+
+ if (error) {
+ for (i = 0; i < argc && argv[i]; ++i)
+ fprintf(stderr, "%s%s", i > 0 ? " " : "", argv[i]);
+ fprintf(stderr, "\n");
+ }
+
+ free(argv);
+ return ret;
+}
+
/* event handling */
@@ -293,7 +350,7 @@ void redraw() {
}
void on_keypress(XKeyEvent *kev) {
- int x, y;
+ int i, x, y;
unsigned int w, h;
char key;
KeySym ksym;
@@ -305,6 +362,25 @@ void on_keypress(XKeyEvent *kev) {
XLookupString(kev, &key, 1, &ksym, NULL);
changed = 0;
+ /* external commands from commands.h */
+ for (i = 0; i < LEN(commands); ++i) {
+ if (commands[i].ksym == ksym) {
+ win_set_cursor(&win, CURSOR_WATCH);
+ if (run_command(commands[i].cmdline, commands[i].reload)) {
+ if (mode == MODE_NORMAL) {
+ img_close(&img, 1);
+ load_image(fileidx);
+ tns_load(&tns, &win, fileidx, filenames[fileidx]);
+ } else {
+ tns_load(&tns, &win, tns.sel, filenames[tns.sel]);
+ }
+ redraw();
+ }
+ win_set_cursor(&win, mode == MODE_NORMAL ? CURSOR_NONE : CURSOR_ARROW);
+ return;
+ }
+ }
+
if (mode == MODE_NORMAL) {
switch (ksym) {
/* navigate image list */
@@ -395,7 +471,7 @@ void on_keypress(XKeyEvent *kev) {
case XK_Return:
if (!tns.thumbs)
tns_init(&tns, filecnt);
- img_close(&img);
+ img_close(&img, 0);
mode = MODE_THUMBS;
win_set_cursor(&win, CURSOR_ARROW);
timo_cursor = 0;
diff --git a/thumbs.c b/thumbs.c
index df44c6f..78380ec 100644
--- a/thumbs.c
+++ b/thumbs.c
@@ -66,12 +66,10 @@ void tns_load(tns_t *tns, win_t *win, int n, const char *filename) {
else if (n >= tns->cnt)
tns->cnt = n + 1;
- if ((im = imlib_load_image(filename))) {
+ if ((im = imlib_load_image(filename)))
imlib_context_set_image(im);
- imlib_image_set_changes_on_disk();
- } else {
+ else
imlib_context_set_image(im_broken);
- }
w = imlib_image_get_width();
h = imlib_image_get_height();
@@ -95,7 +93,7 @@ void tns_load(tns_t *tns, win_t *win, int n, const char *filename) {
tns->dirty = 1;
if (im)
- imlib_free_image();
+ imlib_free_image_and_decache();
}
void tns_check_view(tns_t *tns, Bool scrolled) {
diff --git a/window.c b/window.c
index d50d2f2..200e1c5 100644
--- a/window.c
+++ b/window.c
@@ -331,4 +331,6 @@ void win_set_cursor(win_t *win, win_cur_t cursor) {
XDefineCursor(win->env.dpy, win->xwin, carrow);
break;
}
+
+ XFlush(win->env.dpy);
}