Support for external commands like mogrify & jpegtran
This commit is contained in:
parent
955c39a5c5
commit
c05fd44bdd
|
@ -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 },
|
||||
};
|
5
image.c
5
image.c
|
@ -99,9 +99,12 @@ 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);
|
||||
if (decache)
|
||||
imlib_free_image_and_decache();
|
||||
else
|
||||
imlib_free_image();
|
||||
img->im = NULL;
|
||||
}
|
||||
|
|
2
image.h
2
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*);
|
||||
|
||||
|
|
84
main.c
84
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;
|
||||
|
|
8
thumbs.c
8
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) {
|
||||
|
|
Loading…
Reference in New Issue