diff options
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | commands.c | 66 | ||||
| -rw-r--r-- | commands.h | 2 | ||||
| -rw-r--r-- | config.def.h | 17 | ||||
| -rw-r--r-- | exec/image-info (renamed from image-info) | 0 | ||||
| -rw-r--r-- | exec/key-handler | 19 | ||||
| -rw-r--r-- | main.c | 90 | 
7 files changed, 98 insertions, 100 deletions
| @@ -35,8 +35,8 @@ install: all  	sed "s!PREFIX!$(PREFIX)!g; s!VERSION!$(VERSION)!g" sxiv.1 > $(DESTDIR)$(MANPREFIX)/man1/sxiv.1  	chmod 644 $(DESTDIR)$(MANPREFIX)/man1/sxiv.1  	mkdir -p $(DESTDIR)$(PREFIX)/share/sxiv/exec -	cp image-info $(DESTDIR)$(PREFIX)/share/sxiv/exec/image-info -	chmod 755 $(DESTDIR)$(PREFIX)/share/sxiv/exec/image-info +	cp exec/* $(DESTDIR)$(PREFIX)/share/sxiv/exec/ +	chmod 755 $(DESTDIR)$(PREFIX)/share/sxiv/exec/*  uninstall:  	rm -f $(DESTDIR)$(PREFIX)/bin/sxiv @@ -504,69 +504,3 @@ bool it_toggle_alpha(arg_t a)  	return true;  } -bool it_open_with(arg_t a) -{ -	const char *prog = (const char*) a; -	pid_t pid; - -	if (prog == NULL || *prog == '\0') -		return false; - -	if ((pid = fork()) == 0) { -		execlp(prog, prog, -		       files[mode == MODE_IMAGE ? fileidx : tns.sel].path, NULL); -		warn("could not exec: %s", prog); -		exit(EXIT_FAILURE); -	} else if (pid < 0) { -		warn("could not fork. program was: %s", prog); -	} -	return false; -} - -bool it_shell_cmd(arg_t a) -{ -	int n, status; -	const char *cmdline = (const char*) a; -	pid_t pid; - -	if (cmdline == NULL || *cmdline == '\0') -		return false; - -	n = mode == MODE_IMAGE ? fileidx : tns.sel; - -	if (setenv("SXIV_IMG", files[n].path, 1) < 0) { -		warn("could not set env.-variable: SXIV_IMG. command line was: %s", -		     cmdline); -		return false; -	} - -	if ((pid = fork()) == 0) { -		execl("/bin/sh", "/bin/sh", "-c", cmdline, NULL); -		warn("could not exec: /bin/sh. command line was: %s", cmdline); -		exit(EXIT_FAILURE); -	} else if (pid < 0) { -		warn("could not fork. command line was: %s", cmdline); -		return false; -	} - -	win_set_cursor(&win, CURSOR_WATCH); - -	waitpid(pid, &status, 0); -	if (WIFEXITED(status) == 0 || WEXITSTATUS(status) != 0) -		warn("child exited with non-zero return value: %d. command line was: %s", -		     WEXITSTATUS(status), cmdline); -	 -	if (mode == MODE_IMAGE) { -		img_close(&img, true); -		load_image(fileidx); -	} -	if (!tns_load(&tns, n, &files[n], true, mode == MODE_IMAGE) && -	    mode == MODE_THUMB) -	{ -		remove_file(tns.sel, false); -		tns.dirty = true; -		if (tns.sel >= tns.cnt) -			tns.sel = tns.cnt - 1; -	} -	return true; -} @@ -69,7 +69,5 @@ bool i_flip(arg_t);  bool i_toggle_antialias(arg_t);  bool i_change_gamma(arg_t);  bool it_toggle_alpha(arg_t); -bool it_open_with(arg_t); -bool it_shell_cmd(arg_t);  #endif /* COMMANDS_H */ diff --git a/config.def.h b/config.def.h index 6a0f1dc..86ba0f5 100644 --- a/config.def.h +++ b/config.def.h @@ -151,23 +151,6 @@ static const keymap_t keys[] = {  	{ 0,            XK_braceleft,     i_change_gamma,       (arg_t) -1 },  	{ 0,            XK_braceright,    i_change_gamma,       (arg_t) +1 },  	{ ControlMask,  XK_G,             i_change_gamma,       (arg_t)  0 }, - -	/* open current image with given program: */ -	{ ControlMask,  XK_g,             it_open_with,         (arg_t) "gimp" }, - -	/* run shell command line on current file ("$SXIV_IMG"): */ -	{ ControlMask,  XK_less,          it_shell_cmd,         (arg_t) \ -			"mogrify -rotate -90 \"$SXIV_IMG\"" }, -	{ ControlMask,  XK_greater,       it_shell_cmd,         (arg_t) \ -			"mogrify -rotate +90 \"$SXIV_IMG\"" }, -	{ ControlMask,  XK_question,      it_shell_cmd,         (arg_t) \ -			"mogrify -rotate 180 \"$SXIV_IMG\"" }, -	{ ControlMask,  XK_comma,         it_shell_cmd,         (arg_t) \ -			"jpegtran -rotate 270 -copy all -outfile \"$SXIV_IMG\" \"$SXIV_IMG\"" }, -	{ ControlMask,  XK_period,        it_shell_cmd,         (arg_t) \ -			"jpegtran -rotate  90 -copy all -outfile \"$SXIV_IMG\" \"$SXIV_IMG\"" }, -	{ ControlMask,  XK_slash,         it_shell_cmd,         (arg_t) \ -			"jpegtran -rotate 180 -copy all -outfile \"$SXIV_IMG\" \"$SXIV_IMG\"" },  };  /* mouse button mappings for image mode: */ diff --git a/image-info b/exec/image-info index 7814c2d..7814c2d 100644 --- a/image-info +++ b/exec/image-info diff --git a/exec/key-handler b/exec/key-handler new file mode 100644 index 0000000..d2e8aa2 --- /dev/null +++ b/exec/key-handler @@ -0,0 +1,19 @@ +#!/bin/sh + +case "$1" in +"C-g") +	gimp "$2" & ;; +"C-comma") +	exec jpegtran -rotate 270 -copy all -outfile "$2" "$2" ;; +"C-period") +	exec jpegtran -rotate  90 -copy all -outfile "$2" "$2" ;; +"C-slash") +	exec jpegtran -rotate 180 -copy all -outfile "$2" "$2" ;; +"C-less") +	exec mogrify -rotate -90 "$2" ;; +"C-greater") +	exec mogrify -rotate +90 "$2" ;; +"C-question") +	exec mogrify -rotate 180 "$2" ;; +esac + @@ -46,6 +46,18 @@ enum {  	TITLE_LEN    = 256  }; +#define EXEC_REL_DIR ".sxiv/exec" + +enum { +	EXEC_INFO, +	EXEC_KEY +}; + +typedef struct { +	const char *name; +	char *cmd; +} exec_t; +  typedef struct {  	struct timeval when;  	bool active; @@ -71,9 +83,13 @@ int prefix;  bool resized = false; -const char * const INFO_SCRIPT = ".sxiv/exec/image-info"; +exec_t exec[] = { +	{ "image-info",  NULL }, +	{ "key-handler", NULL } +}; +  struct { -  char *script; +  char *cmd;    int fd;    unsigned int i, lastsep;    bool open; @@ -221,7 +237,7 @@ void open_info(void)  	static pid_t pid;  	int pfd[2]; -	if (info.script == NULL || info.open || win.bar.h == 0) +	if (info.cmd == NULL || info.open || win.bar.h == 0)  		return;  	if (info.fd != -1) {  		close(info.fd); @@ -242,8 +258,8 @@ void open_info(void)  	} else if (pid == 0) {  		close(pfd[0]);  		dup2(pfd[1], 1); -		execl(info.script, info.script, files[fileidx].name, NULL); -		warn("could not exec: %s", info.script); +		execl(info.cmd, info.cmd, files[fileidx].name, NULL); +		warn("could not exec: %s", info.cmd);  		exit(EXIT_FAILURE);  	}  } @@ -356,7 +372,7 @@ void update_info(void)  			              fn, img.multi.sel + 1, img.multi.cnt);  		}  		n += snprintf(rt + n, rlen - n, "%0*d/%d", fw, sel + 1, filecnt); -		ow_info = info.script == NULL; +		ow_info = info.cmd == NULL;  	}  	if (ow_info) {  		fn = strlen(files[sel].name); @@ -418,6 +434,49 @@ void clear_resize(void)  	resized = false;  } +void key_handler(const char *key, unsigned int mask) +{ +	pid_t pid; +	int retval, status, n = mode == MODE_IMAGE ? fileidx : tns.sel; +	char *cmd = exec[EXEC_KEY].cmd, kstr[32]; + +	if (cmd == NULL || key == NULL) +		return; + +	snprintf(kstr, sizeof(kstr), "%s%s%s%s", +	         mask & ControlMask ? "C-" : "", +	         mask & Mod1Mask    ? "M-" : "", +	         mask & ShiftMask   ? "S-" : "", key); + +	if ((pid = fork()) == 0) { +		execl(cmd, cmd, kstr, files[n].path, NULL); +		warn("could not exec key handler"); +		exit(EXIT_FAILURE); +	} else if (pid < 0) { +		warn("could not fork key handler"); +		return; +	} +	win_set_cursor(&win, CURSOR_WATCH); + +	waitpid(pid, &status, 0); +	retval = WEXITSTATUS(status); +	if (WIFEXITED(status) == 0 || retval != 0) +		warn("key handler exited with non-zero return value: %d", retval); +	if (mode == MODE_IMAGE) { +		img_close(&img, true); +		load_image(fileidx); +	} +	if (!tns_load(&tns, n, &files[n], true, mode == MODE_IMAGE) && +	    mode == MODE_THUMB) +	{ +		remove_file(tns.sel, false); +		tns.dirty = true; +		if (tns.sel >= tns.cnt) +			tns.sel = tns.cnt - 1; +	} +	redraw(); +} +  #define MODMASK(mask) ((mask) & (ShiftMask|ControlMask|Mod1Mask))  void on_keypress(XKeyEvent *kev) @@ -438,6 +497,9 @@ void on_keypress(XKeyEvent *kev)  	XLookupString(kev, &key, 1, &ksym, NULL);  	sh = (kev->state & ShiftMask) && ksym != shksym ? ShiftMask : 0; +	if (IsModifierKey(ksym)) +		return; +  	if ((ksym == XK_Escape && MODMASK(kev->state) == 0) ||  		  (key >= '0' && key <= '9'))  	{ @@ -456,6 +518,7 @@ void on_keypress(XKeyEvent *kev)  			return;  		}  	} +	key_handler(XKeysymToString(ksym), kev->state & ~sh);  }  void on_buttonpress(XButtonEvent *bev) @@ -706,16 +769,17 @@ int main(int argc, char **argv)  	if ((homedir = getenv("HOME")) == NULL) {  		warn("could not locate home directory"); -	} else { -		len = strlen(homedir) + strlen(INFO_SCRIPT) + 2; -		info.script = (char*) s_malloc(len); -		snprintf(info.script, len, "%s/%s", homedir, INFO_SCRIPT); -		if (access(info.script, X_OK) != 0) { -			free(info.script); -			info.script = NULL; +	} else for (i = 0; i < ARRLEN(exec); i++) { +		len = strlen(homedir) + strlen(EXEC_REL_DIR) + strlen(exec[i].name) + 3; +		exec[i].cmd = (char*) s_malloc(len); +		snprintf(exec[i].cmd, len, "%s/%s/%s", homedir, EXEC_REL_DIR, exec[i].name); +		if (access(exec[i].cmd, X_OK) != 0) { +			free(exec[i].cmd); +			exec[i].cmd = NULL;  		}  	}  	info.fd = -1; +	info.cmd = exec[EXEC_INFO].cmd;  	if (options->thumb_mode) {  		mode = MODE_THUMB; | 
