Krolyxon
Commit c05fd44

Branches

Refs →

nsxivc05fd44

Support for external commands like mogrify & jpegtran

Author
Bert
Date
2011-03-01 18:49 +0100
Parent
955c39a
Commit
c05fd44bdda2934fa6f2f83b776038659f9d7d71

+115 −12

6 files changed

  1. A commands.h +24 −0
  2. M image.c +5 −2
  3. M image.h +1 −1
  4. M main.c +80 −4
  5. M thumbs.c +3 −5
  6. M window.c +2 −0
A commands.h View
@@ -0,0 +1,24 @@
1+#define FILENAME (const char*) 0x1
2+
3+typedef struct {
4+ KeySym ksym;
5+ const char **cmdline;
6+ Bool reload;
7+} command_t;
8+
9+static const char *cmdline_1[] = { "jpegtran", "-rotate", "270", "-copy", "all",
10+ "-outfile", FILENAME, FILENAME, NULL };
11+static const char *cmdline_2[] = { "jpegtran", "-rotate", "90", "-copy", "all",
12+ "-outfile", FILENAME, FILENAME, NULL };
13+static const char *cmdline_3[] = { "mogrify", "-rotate", "-90", FILENAME,
14+ NULL };
15+static const char *cmdline_4[] = { "mogrify", "-rotate", "+90", FILENAME,
16+ NULL };
17+
18+static command_t commands[] = {
19+ /* key command-line reload? */
20+ { XK_a, cmdline_1, True },
21+ { XK_s, cmdline_2, True },
22+ { XK_A, cmdline_3, True },
23+ { XK_S, cmdline_4, True },
24+};
M image.c View
@@ -99,10 +99,13 @@ int img_load(img_t *img, const char *filename) {
9999 return 1;
100100 }
101101
102−void img_close(img_t *img) {
102+void img_close(img_t *img, int decache) {
103103 if (img && img->im) {
104104 imlib_context_set_image(img->im);
105− imlib_free_image();
105+ if (decache)
106+ imlib_free_image_and_decache();
107+ else
108+ imlib_free_image();
106109 img->im = NULL;
107110 }
108111 }
M image.h View
@@ -57,7 +57,7 @@ void img_free(img_t*);
5757
5858 int img_check(const char*);
5959 int img_load(img_t*, const char*);
60−void img_close(img_t*);
60+void img_close(img_t*, int);
6161
6262 void img_render(img_t*, win_t*);
6363
M main.c View
@@ -23,6 +23,8 @@
2323 #include <sys/select.h>
2424 #include <sys/stat.h>
2525 #include <sys/time.h>
26+#include <sys/wait.h>
27+#include <unistd.h>
2628
2729 #include <X11/Xlib.h>
2830 #include <X11/Xutil.h>
@@ -33,6 +35,7 @@
3335 #include "thumbs.h"
3436 #include "util.h"
3537 #include "window.h"
38+#include "commands.h"
3639
3740 typedef enum {
3841 MODE_NORMAL = 0,
@@ -62,7 +65,7 @@ void cleanup() {
6265 static int in = 0;
6366
6467 if (!in++) {
65− img_close(&img);
68+ img_close(&img, 0);
6669 img_free(&img);
6770 tns_free(&tns, &win);
6871 win_close(&win);
@@ -73,7 +76,7 @@ int load_image(int new) {
7376 struct stat fstats;
7477
7578 if (new >= 0 && new < filecnt) {
76− img_close(&img);
79+ img_close(&img, 0);
7780 fileidx = new;
7881 if (!stat(filenames[fileidx], &fstats))
7982 filesize = fstats.st_size;
@@ -270,6 +273,60 @@ void read_dir_rec(const char *dirname) {
270273 free(dirnames);
271274 }
272275
276+int run_command(const char **cmdline, Bool reload) {
277+ int argc, i;
278+ const char **argv;
279+ pid_t pid;
280+ int error, ret, status;
281+
282+ if (!cmdline)
283+ return 0;
284+
285+ argc = 1;
286+ while (cmdline[argc-1])
287+ ++argc;
288+
289+ if (argc < 2)
290+ return 0;
291+
292+ argv = (const char**) s_malloc(argc * sizeof(const char*));
293+ error = ret = 0;
294+
295+ for (i = 0; i < argc; ++i) {
296+ if (cmdline[i] != FILENAME)
297+ argv[i] = cmdline[i];
298+ else
299+ argv[i] = filenames[mode == MODE_NORMAL ? fileidx : tns.sel];
300+ }
301+
302+ if ((pid = fork()) == 0) {
303+ execvp(argv[0], (char **const) argv);
304+ warn("could not exec %s", argv[0]);
305+ exit(1);
306+ } else if (pid < 0 && !options->quiet) {
307+ warn("could not fork. command line was:");
308+ error = 1;
309+ } else if (reload) {
310+ waitpid(pid, &status, 0);
311+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
312+ ret = 1;
313+ } else if (!options->quiet) {
314+ warn("child exited with non-zero return value: %d. command line was:",
315+ WEXITSTATUS(status));
316+ error = 1;
317+ }
318+ }
319+
320+ if (error) {
321+ for (i = 0; i < argc && argv[i]; ++i)
322+ fprintf(stderr, "%s%s", i > 0 ? " " : "", argv[i]);
323+ fprintf(stderr, "\n");
324+ }
325+
326+ free(argv);
327+ return ret;
328+}
329+
273330
274331 /* event handling */
275332
@@ -293,7 +350,7 @@ void redraw() {
293350 }
294351
295352 void on_keypress(XKeyEvent *kev) {
296− int x, y;
353+ int i, x, y;
297354 unsigned int w, h;
298355 char key;
299356 KeySym ksym;
@@ -305,6 +362,25 @@ void on_keypress(XKeyEvent *kev) {
305362 XLookupString(kev, &key, 1, &ksym, NULL);
306363 changed = 0;
307364
365+ /* external commands from commands.h */
366+ for (i = 0; i < LEN(commands); ++i) {
367+ if (commands[i].ksym == ksym) {
368+ win_set_cursor(&win, CURSOR_WATCH);
369+ if (run_command(commands[i].cmdline, commands[i].reload)) {
370+ if (mode == MODE_NORMAL) {
371+ img_close(&img, 1);
372+ load_image(fileidx);
373+ tns_load(&tns, &win, fileidx, filenames[fileidx]);
374+ } else {
375+ tns_load(&tns, &win, tns.sel, filenames[tns.sel]);
376+ }
377+ redraw();
378+ }
379+ win_set_cursor(&win, mode == MODE_NORMAL ? CURSOR_NONE : CURSOR_ARROW);
380+ return;
381+ }
382+ }
383+
308384 if (mode == MODE_NORMAL) {
309385 switch (ksym) {
310386 /* navigate image list */
@@ -395,7 +471,7 @@ void on_keypress(XKeyEvent *kev) {
395471 case XK_Return:
396472 if (!tns.thumbs)
397473 tns_init(&tns, filecnt);
398− img_close(&img);
474+ img_close(&img, 0);
399475 mode = MODE_THUMBS;
400476 win_set_cursor(&win, CURSOR_ARROW);
401477 timo_cursor = 0;
M thumbs.c View
@@ -66,12 +66,10 @@ void tns_load(tns_t *tns, win_t *win, int n, const char *filename) {
6666 else if (n >= tns->cnt)
6767 tns->cnt = n + 1;
6868
69− if ((im = imlib_load_image(filename))) {
69+ if ((im = imlib_load_image(filename)))
7070 imlib_context_set_image(im);
71− imlib_image_set_changes_on_disk();
72− } else {
71+ else
7372 imlib_context_set_image(im_broken);
74− }
7573
7674 w = imlib_image_get_width();
7775 h = imlib_image_get_height();
@@ -95,7 +93,7 @@ void tns_load(tns_t *tns, win_t *win, int n, const char *filename) {
9593 tns->dirty = 1;
9694
9795 if (im)
98− imlib_free_image();
96+ imlib_free_image_and_decache();
9997 }
10098
10199 void tns_check_view(tns_t *tns, Bool scrolled) {
M window.c View
@@ -331,4 +331,6 @@ void win_set_cursor(win_t *win, win_cur_t cursor) {
331331 XDefineCursor(win->env.dpy, win->xwin, carrow);
332332 break;
333333 }
334+
335+ XFlush(win->env.dpy);
334336 }