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 }, | ||||||
|  | }; | ||||||
							
								
								
									
										5
									
								
								image.c
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								image.c
									
									
									
									
									
								
							| @ -99,9 +99,12 @@ 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); | ||||||
|  | 		if (decache) | ||||||
|  | 			imlib_free_image_and_decache(); | ||||||
|  | 		else | ||||||
| 			imlib_free_image(); | 			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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Bert
						Bert