Support for external commands like mogrify & jpegtran
This commit is contained in:
parent
955c39a5c5
commit
c05fd44bdd
24
commands.h
Normal file
24
commands.h
Normal file
@ -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 },
|
||||||
|
};
|
7
image.c
7
image.c
@ -99,10 +99,13 @@ int img_load(img_t *img, const char *filename) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void img_close(img_t *img) {
|
void img_close(img_t *img, int decache) {
|
||||||
if (img && img->im) {
|
if (img && img->im) {
|
||||||
imlib_context_set_image(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;
|
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_check(const char*);
|
||||||
int img_load(img_t*, 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*);
|
void img_render(img_t*, win_t*);
|
||||||
|
|
||||||
|
84
main.c
84
main.c
@ -23,6 +23,8 @@
|
|||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
@ -33,6 +35,7 @@
|
|||||||
#include "thumbs.h"
|
#include "thumbs.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
#include "commands.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MODE_NORMAL = 0,
|
MODE_NORMAL = 0,
|
||||||
@ -62,7 +65,7 @@ void cleanup() {
|
|||||||
static int in = 0;
|
static int in = 0;
|
||||||
|
|
||||||
if (!in++) {
|
if (!in++) {
|
||||||
img_close(&img);
|
img_close(&img, 0);
|
||||||
img_free(&img);
|
img_free(&img);
|
||||||
tns_free(&tns, &win);
|
tns_free(&tns, &win);
|
||||||
win_close(&win);
|
win_close(&win);
|
||||||
@ -73,7 +76,7 @@ int load_image(int new) {
|
|||||||
struct stat fstats;
|
struct stat fstats;
|
||||||
|
|
||||||
if (new >= 0 && new < filecnt) {
|
if (new >= 0 && new < filecnt) {
|
||||||
img_close(&img);
|
img_close(&img, 0);
|
||||||
fileidx = new;
|
fileidx = new;
|
||||||
if (!stat(filenames[fileidx], &fstats))
|
if (!stat(filenames[fileidx], &fstats))
|
||||||
filesize = fstats.st_size;
|
filesize = fstats.st_size;
|
||||||
@ -270,6 +273,60 @@ void read_dir_rec(const char *dirname) {
|
|||||||
free(dirnames);
|
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 */
|
/* event handling */
|
||||||
|
|
||||||
@ -293,7 +350,7 @@ void redraw() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void on_keypress(XKeyEvent *kev) {
|
void on_keypress(XKeyEvent *kev) {
|
||||||
int x, y;
|
int i, x, y;
|
||||||
unsigned int w, h;
|
unsigned int w, h;
|
||||||
char key;
|
char key;
|
||||||
KeySym ksym;
|
KeySym ksym;
|
||||||
@ -305,6 +362,25 @@ void on_keypress(XKeyEvent *kev) {
|
|||||||
XLookupString(kev, &key, 1, &ksym, NULL);
|
XLookupString(kev, &key, 1, &ksym, NULL);
|
||||||
changed = 0;
|
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) {
|
if (mode == MODE_NORMAL) {
|
||||||
switch (ksym) {
|
switch (ksym) {
|
||||||
/* navigate image list */
|
/* navigate image list */
|
||||||
@ -395,7 +471,7 @@ void on_keypress(XKeyEvent *kev) {
|
|||||||
case XK_Return:
|
case XK_Return:
|
||||||
if (!tns.thumbs)
|
if (!tns.thumbs)
|
||||||
tns_init(&tns, filecnt);
|
tns_init(&tns, filecnt);
|
||||||
img_close(&img);
|
img_close(&img, 0);
|
||||||
mode = MODE_THUMBS;
|
mode = MODE_THUMBS;
|
||||||
win_set_cursor(&win, CURSOR_ARROW);
|
win_set_cursor(&win, CURSOR_ARROW);
|
||||||
timo_cursor = 0;
|
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)
|
else if (n >= tns->cnt)
|
||||||
tns->cnt = n + 1;
|
tns->cnt = n + 1;
|
||||||
|
|
||||||
if ((im = imlib_load_image(filename))) {
|
if ((im = imlib_load_image(filename)))
|
||||||
imlib_context_set_image(im);
|
imlib_context_set_image(im);
|
||||||
imlib_image_set_changes_on_disk();
|
else
|
||||||
} else {
|
|
||||||
imlib_context_set_image(im_broken);
|
imlib_context_set_image(im_broken);
|
||||||
}
|
|
||||||
|
|
||||||
w = imlib_image_get_width();
|
w = imlib_image_get_width();
|
||||||
h = imlib_image_get_height();
|
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;
|
tns->dirty = 1;
|
||||||
|
|
||||||
if (im)
|
if (im)
|
||||||
imlib_free_image();
|
imlib_free_image_and_decache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void tns_check_view(tns_t *tns, Bool scrolled) {
|
void tns_check_view(tns_t *tns, Bool scrolled) {
|
||||||
|
Loading…
Reference in New Issue
Block a user