Krolyxon
Commit f2e0c49

Branches

Refs →

nsxivf2e0c49

Moved external shell commands into exec/key-handler script

Gets called on all unset key mappings. Arguments are: key combo and
current file. Thanks to Francesco Orsenigo (xarvh) for the idea.
Author
Bert Münnich
Date
2014-01-02 23:19 +0100
Parent
b2eae52
Commit
f2e0c492bd784a3a927550187e21cfbc6bbb0939

+98 −100

7 files changed

  1. M Makefile +2 −2
  2. M commands.c +0 −66
  3. M commands.h +0 −2
  4. M config.def.h +0 −17
  5. R image-info → exec/image-info +0 −0
  6. A exec/key-handler +19 −0
  7. M main.c +77 −13
M Makefile View
@@ -35,8 +35,8 @@ install: all
3535 sed "s!PREFIX!$(PREFIX)!g; s!VERSION!$(VERSION)!g" sxiv.1 > $(DESTDIR)$(MANPREFIX)/man1/sxiv.1
3636 chmod 644 $(DESTDIR)$(MANPREFIX)/man1/sxiv.1
3737 mkdir -p $(DESTDIR)$(PREFIX)/share/sxiv/exec
38− cp image-info $(DESTDIR)$(PREFIX)/share/sxiv/exec/image-info
39− chmod 755 $(DESTDIR)$(PREFIX)/share/sxiv/exec/image-info
38+ cp exec/* $(DESTDIR)$(PREFIX)/share/sxiv/exec/
39+ chmod 755 $(DESTDIR)$(PREFIX)/share/sxiv/exec/*
4040
4141 uninstall:
4242 rm -f $(DESTDIR)$(PREFIX)/bin/sxiv
M commands.c View
@@ -504,69 +504,3 @@ bool it_toggle_alpha(arg_t a)
504504 return true;
505505 }
506506
507−bool it_open_with(arg_t a)
508−{
509− const char *prog = (const char*) a;
510− pid_t pid;
511−
512− if (prog == NULL || *prog == '\0')
513− return false;
514−
515− if ((pid = fork()) == 0) {
516− execlp(prog, prog,
517− files[mode == MODE_IMAGE ? fileidx : tns.sel].path, NULL);
518− warn("could not exec: %s", prog);
519− exit(EXIT_FAILURE);
520− } else if (pid < 0) {
521− warn("could not fork. program was: %s", prog);
522− }
523− return false;
524−}
525−
526−bool it_shell_cmd(arg_t a)
527−{
528− int n, status;
529− const char *cmdline = (const char*) a;
530− pid_t pid;
531−
532− if (cmdline == NULL || *cmdline == '\0')
533− return false;
534−
535− n = mode == MODE_IMAGE ? fileidx : tns.sel;
536−
537− if (setenv("SXIV_IMG", files[n].path, 1) < 0) {
538− warn("could not set env.-variable: SXIV_IMG. command line was: %s",
539− cmdline);
540− return false;
541− }
542−
543− if ((pid = fork()) == 0) {
544− execl("/bin/sh", "/bin/sh", "-c", cmdline, NULL);
545− warn("could not exec: /bin/sh. command line was: %s", cmdline);
546− exit(EXIT_FAILURE);
547− } else if (pid < 0) {
548− warn("could not fork. command line was: %s", cmdline);
549− return false;
550− }
551−
552− win_set_cursor(&win, CURSOR_WATCH);
553−
554− waitpid(pid, &status, 0);
555− if (WIFEXITED(status) == 0 || WEXITSTATUS(status) != 0)
556− warn("child exited with non-zero return value: %d. command line was: %s",
557− WEXITSTATUS(status), cmdline);
558−
559− if (mode == MODE_IMAGE) {
560− img_close(&img, true);
561− load_image(fileidx);
562− }
563− if (!tns_load(&tns, n, &files[n], true, mode == MODE_IMAGE) &&
564− mode == MODE_THUMB)
565− {
566− remove_file(tns.sel, false);
567− tns.dirty = true;
568− if (tns.sel >= tns.cnt)
569− tns.sel = tns.cnt - 1;
570− }
571− return true;
572−}
M commands.h View
@@ -69,7 +69,5 @@ bool i_flip(arg_t);
6969 bool i_toggle_antialias(arg_t);
7070 bool i_change_gamma(arg_t);
7171 bool it_toggle_alpha(arg_t);
72−bool it_open_with(arg_t);
73−bool it_shell_cmd(arg_t);
7472
7573 #endif /* COMMANDS_H */
M config.def.h View
@@ -151,23 +151,6 @@ static const keymap_t keys[] = {
151151 { 0, XK_braceleft, i_change_gamma, (arg_t) -1 },
152152 { 0, XK_braceright, i_change_gamma, (arg_t) +1 },
153153 { ControlMask, XK_G, i_change_gamma, (arg_t) 0 },
154−
155− /* open current image with given program: */
156− { ControlMask, XK_g, it_open_with, (arg_t) "gimp" },
157−
158− /* run shell command line on current file ("$SXIV_IMG"): */
159− { ControlMask, XK_less, it_shell_cmd, (arg_t) \
160− "mogrify -rotate -90 \"$SXIV_IMG\"" },
161− { ControlMask, XK_greater, it_shell_cmd, (arg_t) \
162− "mogrify -rotate +90 \"$SXIV_IMG\"" },
163− { ControlMask, XK_question, it_shell_cmd, (arg_t) \
164− "mogrify -rotate 180 \"$SXIV_IMG\"" },
165− { ControlMask, XK_comma, it_shell_cmd, (arg_t) \
166− "jpegtran -rotate 270 -copy all -outfile \"$SXIV_IMG\" \"$SXIV_IMG\"" },
167− { ControlMask, XK_period, it_shell_cmd, (arg_t) \
168− "jpegtran -rotate 90 -copy all -outfile \"$SXIV_IMG\" \"$SXIV_IMG\"" },
169− { ControlMask, XK_slash, it_shell_cmd, (arg_t) \
170− "jpegtran -rotate 180 -copy all -outfile \"$SXIV_IMG\" \"$SXIV_IMG\"" },
171154 };
172155
173156 /* mouse button mappings for image mode: */
R image-info → exec/image-info View

[No content changes]

A exec/key-handler View
@@ -0,0 +1,19 @@
1+#!/bin/sh
2+
3+case "$1" in
4+"C-g")
5+ gimp "$2" & ;;
6+"C-comma")
7+ exec jpegtran -rotate 270 -copy all -outfile "$2" "$2" ;;
8+"C-period")
9+ exec jpegtran -rotate 90 -copy all -outfile "$2" "$2" ;;
10+"C-slash")
11+ exec jpegtran -rotate 180 -copy all -outfile "$2" "$2" ;;
12+"C-less")
13+ exec mogrify -rotate -90 "$2" ;;
14+"C-greater")
15+ exec mogrify -rotate +90 "$2" ;;
16+"C-question")
17+ exec mogrify -rotate 180 "$2" ;;
18+esac
19+
M main.c View
@@ -46,6 +46,18 @@ enum {
4646 TITLE_LEN = 256
4747 };
4848
49+#define EXEC_REL_DIR ".sxiv/exec"
50+
51+enum {
52+ EXEC_INFO,
53+ EXEC_KEY
54+};
55+
56+typedef struct {
57+ const char *name;
58+ char *cmd;
59+} exec_t;
60+
4961 typedef struct {
5062 struct timeval when;
5163 bool active;
@@ -71,9 +83,13 @@ int prefix;
7183
7284 bool resized = false;
7385
74−const char * const INFO_SCRIPT = ".sxiv/exec/image-info";
86+exec_t exec[] = {
87+ { "image-info", NULL },
88+ { "key-handler", NULL }
89+};
90+
7591 struct {
76− char *script;
92+ char *cmd;
7793 int fd;
7894 unsigned int i, lastsep;
7995 bool open;
@@ -221,7 +237,7 @@ void open_info(void)
221237 static pid_t pid;
222238 int pfd[2];
223239
224− if (info.script == NULL || info.open || win.bar.h == 0)
240+ if (info.cmd == NULL || info.open || win.bar.h == 0)
225241 return;
226242 if (info.fd != -1) {
227243 close(info.fd);
@@ -242,8 +258,8 @@ void open_info(void)
242258 } else if (pid == 0) {
243259 close(pfd[0]);
244260 dup2(pfd[1], 1);
245− execl(info.script, info.script, files[fileidx].name, NULL);
246− warn("could not exec: %s", info.script);
261+ execl(info.cmd, info.cmd, files[fileidx].name, NULL);
262+ warn("could not exec: %s", info.cmd);
247263 exit(EXIT_FAILURE);
248264 }
249265 }
@@ -356,7 +372,7 @@ void update_info(void)
356372 fn, img.multi.sel + 1, img.multi.cnt);
357373 }
358374 n += snprintf(rt + n, rlen - n, "%0*d/%d", fw, sel + 1, filecnt);
359− ow_info = info.script == NULL;
375+ ow_info = info.cmd == NULL;
360376 }
361377 if (ow_info) {
362378 fn = strlen(files[sel].name);
@@ -418,6 +434,49 @@ void clear_resize(void)
418434 resized = false;
419435 }
420436
437+void key_handler(const char *key, unsigned int mask)
438+{
439+ pid_t pid;
440+ int retval, status, n = mode == MODE_IMAGE ? fileidx : tns.sel;
441+ char *cmd = exec[EXEC_KEY].cmd, kstr[32];
442+
443+ if (cmd == NULL || key == NULL)
444+ return;
445+
446+ snprintf(kstr, sizeof(kstr), "%s%s%s%s",
447+ mask & ControlMask ? "C-" : "",
448+ mask & Mod1Mask ? "M-" : "",
449+ mask & ShiftMask ? "S-" : "", key);
450+
451+ if ((pid = fork()) == 0) {
452+ execl(cmd, cmd, kstr, files[n].path, NULL);
453+ warn("could not exec key handler");
454+ exit(EXIT_FAILURE);
455+ } else if (pid < 0) {
456+ warn("could not fork key handler");
457+ return;
458+ }
459+ win_set_cursor(&win, CURSOR_WATCH);
460+
461+ waitpid(pid, &status, 0);
462+ retval = WEXITSTATUS(status);
463+ if (WIFEXITED(status) == 0 || retval != 0)
464+ warn("key handler exited with non-zero return value: %d", retval);
465+ if (mode == MODE_IMAGE) {
466+ img_close(&img, true);
467+ load_image(fileidx);
468+ }
469+ if (!tns_load(&tns, n, &files[n], true, mode == MODE_IMAGE) &&
470+ mode == MODE_THUMB)
471+ {
472+ remove_file(tns.sel, false);
473+ tns.dirty = true;
474+ if (tns.sel >= tns.cnt)
475+ tns.sel = tns.cnt - 1;
476+ }
477+ redraw();
478+}
479+
421480 #define MODMASK(mask) ((mask) & (ShiftMask|ControlMask|Mod1Mask))
422481
423482 void on_keypress(XKeyEvent *kev)
@@ -438,6 +497,9 @@ void on_keypress(XKeyEvent *kev)
438497 XLookupString(kev, &key, 1, &ksym, NULL);
439498 sh = (kev->state & ShiftMask) && ksym != shksym ? ShiftMask : 0;
440499
500+ if (IsModifierKey(ksym))
501+ return;
502+
441503 if ((ksym == XK_Escape && MODMASK(kev->state) == 0) ||
442504 (key >= '0' && key <= '9'))
443505 {
@@ -456,6 +518,7 @@ void on_keypress(XKeyEvent *kev)
456518 return;
457519 }
458520 }
521+ key_handler(XKeysymToString(ksym), kev->state & ~sh);
459522 }
460523
461524 void on_buttonpress(XButtonEvent *bev)
@@ -706,16 +769,17 @@ int main(int argc, char **argv)
706769
707770 if ((homedir = getenv("HOME")) == NULL) {
708771 warn("could not locate home directory");
709− } else {
710− len = strlen(homedir) + strlen(INFO_SCRIPT) + 2;
711− info.script = (char*) s_malloc(len);
712− snprintf(info.script, len, "%s/%s", homedir, INFO_SCRIPT);
713− if (access(info.script, X_OK) != 0) {
714− free(info.script);
715− info.script = NULL;
772+ } else for (i = 0; i < ARRLEN(exec); i++) {
773+ len = strlen(homedir) + strlen(EXEC_REL_DIR) + strlen(exec[i].name) + 3;
774+ exec[i].cmd = (char*) s_malloc(len);
775+ snprintf(exec[i].cmd, len, "%s/%s/%s", homedir, EXEC_REL_DIR, exec[i].name);
776+ if (access(exec[i].cmd, X_OK) != 0) {
777+ free(exec[i].cmd);
778+ exec[i].cmd = NULL;
716779 }
717780 }
718781 info.fd = -1;
782+ info.cmd = exec[EXEC_INFO].cmd;
719783
720784 if (options->thumb_mode) {
721785 mode = MODE_THUMB;