New option: -r, open all images in directories
This commit is contained in:
		| @@ -37,6 +37,7 @@ sxiv supports the following command-line options: | |||||||
|                  (see section GEOMETRY SPECIFICATIONS of X(7)) |                  (see section GEOMETRY SPECIFICATIONS of X(7)) | ||||||
|     -p           Pixelize, i.e. turn off image anti-aliasing |     -p           Pixelize, i.e. turn off image anti-aliasing | ||||||
|     -q           Be quiet, disable warnings |     -q           Be quiet, disable warnings | ||||||
|  |     -r           Search given directories recursively for images | ||||||
|     -s           Scale all images to fit into window |     -s           Scale all images to fit into window | ||||||
|     -v           Print version information and exit |     -v           Print version information and exit | ||||||
|     -Z           Same as `-z 100' |     -Z           Same as `-z 100' | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								TODO
									
									
									
									
									
								
							| @@ -1,3 +1,2 @@ | |||||||
| - key mappings for fit image to window and vice versa | - key mappings for fit image to window and vice versa | ||||||
| - update filelist if image is removed or renamed while running | - update filelist if image is removed or renamed while running | ||||||
| - view all images in directories (recursive mode) |  | ||||||
|   | |||||||
							
								
								
									
										79
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								main.c
									
									
									
									
									
								
							| @@ -18,6 +18,8 @@ | |||||||
|  |  | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <dirent.h> | ||||||
| #include <sys/select.h> | #include <sys/select.h> | ||||||
| #include <sys/stat.h> | #include <sys/stat.h> | ||||||
|  |  | ||||||
| @@ -39,7 +41,8 @@ void on_motionnotify(XEvent*); | |||||||
| void on_configurenotify(XEvent*); | void on_configurenotify(XEvent*); | ||||||
|  |  | ||||||
| void update_title(); | void update_title(); | ||||||
| void read_dir(const char*); | void check_append(const char*); | ||||||
|  | void read_dir_rec(const char*); | ||||||
|  |  | ||||||
| static void (*handler[LASTEvent])(XEvent*) = { | static void (*handler[LASTEvent])(XEvent*) = { | ||||||
| 	[KeyPress] = on_keypress, | 	[KeyPress] = on_keypress, | ||||||
| @@ -118,16 +121,11 @@ int main(int argc, char **argv) { | |||||||
| 			WARN("could not stat file: %s", filename); | 			WARN("could not stat file: %s", filename); | ||||||
| 		} else if (S_ISDIR(fstats.st_mode)) { | 		} else if (S_ISDIR(fstats.st_mode)) { | ||||||
| 			if (options->recursive) | 			if (options->recursive) | ||||||
| 				read_dir(filename); | 				read_dir_rec(filename); | ||||||
| 			else | 			else | ||||||
| 				WARN("ignoring directory: %s", filename); | 				WARN("ignoring directory: %s", filename); | ||||||
| 		} else if (img_check(filename)) { | 		} else { | ||||||
| 			if (fileidx == filecnt) { | 			check_append(filename); | ||||||
| 				filecnt *= 2; |  | ||||||
| 				filenames = (const char**) s_realloc(filenames, |  | ||||||
| 				                                     filecnt * sizeof(const char*)); |  | ||||||
| 			} |  | ||||||
| 			filenames[fileidx++] = filename; |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -384,7 +382,68 @@ void update_title() { | |||||||
| 	win_set_title(&win, win_title); | 	win_set_title(&win, win_title); | ||||||
| } | } | ||||||
|  |  | ||||||
| void read_dir(const char *dir) { | void check_append(const char *filename) { | ||||||
|  | 	if (!filename) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	if (img_check(filename)) { | ||||||
|  | 		if (fileidx == filecnt) { | ||||||
|  | 			filecnt *= 2; | ||||||
|  | 			filenames = (const char**) s_realloc(filenames, | ||||||
|  | 																					 filecnt * sizeof(const char*)); | ||||||
|  | 		} | ||||||
|  | 		filenames[fileidx++] = filename; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void read_dir_rec(const char *dirname) { | ||||||
|  | 	char *filename; | ||||||
|  | 	const char **dirnames; | ||||||
|  | 	int dircnt, diridx; | ||||||
|  | 	unsigned char first; | ||||||
|  | 	size_t len; | ||||||
|  | 	DIR *dir; | ||||||
|  | 	struct dirent *dentry; | ||||||
|  | 	struct stat fstats; | ||||||
|  |  | ||||||
|  | 	if (!dirname) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	dircnt = DNAME_CNT; | ||||||
|  | 	diridx = first = 1; | ||||||
|  | 	dirnames = (const char**) s_malloc(dircnt * sizeof(const char*)); | ||||||
|  | 	dirnames[0] = dirname; | ||||||
|  |  | ||||||
|  | 	while (diridx > 0) { | ||||||
|  | 		dirname = dirnames[--diridx]; | ||||||
|  | 		if (!(dir = opendir(dirname))) | ||||||
|  | 			DIE("could not open directory: %s", dirname); | ||||||
|  | 		while ((dentry = readdir(dir))) { | ||||||
|  | 			if (!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, "..")) | ||||||
|  | 				continue; | ||||||
|  | 			len = strlen(dirname) + strlen(dentry->d_name) + 2; | ||||||
|  | 			filename = (char*) s_malloc(len * sizeof(char)); | ||||||
|  | 			snprintf(filename, len, "%s/%s", dirname, dentry->d_name); | ||||||
|  | 			if (stat(filename, &fstats)) { | ||||||
|  | 				WARN("could not stat file: %s", filename); | ||||||
|  | 				free(filename); | ||||||
|  | 			} else if (S_ISDIR(fstats.st_mode)) { | ||||||
|  | 				if (diridx == dircnt) { | ||||||
|  | 					dircnt *= 2; | ||||||
|  | 					dirnames = (const char**) s_realloc(dirnames, | ||||||
|  | 					                                    dircnt * sizeof(const char*)); | ||||||
|  | 				} | ||||||
|  | 				dirnames[diridx++] = filename; | ||||||
|  | 			} else { | ||||||
|  | 				check_append(filename); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		closedir(dir); | ||||||
|  | 		if (!first) | ||||||
|  | 			free((void*) dirname); | ||||||
|  | 		else | ||||||
|  | 			first = 0; | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void* s_malloc(size_t size) { | void* s_malloc(size_t size) { | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ options_t _options; | |||||||
| const options_t *options = (const options_t*) &_options; | const options_t *options = (const options_t*) &_options; | ||||||
|  |  | ||||||
| void print_usage() { | void print_usage() { | ||||||
| 	printf("usage: sxiv [-dFfhpqsvZ] [-g GEOMETRY] [-z ZOOM] FILES...\n"); | 	printf("usage: sxiv [-dFfhpqrsvZ] [-g GEOMETRY] [-z ZOOM] FILES...\n"); | ||||||
| } | } | ||||||
|  |  | ||||||
| void print_version() { | void print_version() { | ||||||
| @@ -52,7 +52,7 @@ void parse_options(int argc, char **argv) { | |||||||
| 	_options.quiet = 0; | 	_options.quiet = 0; | ||||||
| 	_options.recursive = 0; | 	_options.recursive = 0; | ||||||
|  |  | ||||||
| 	while ((opt = getopt(argc, argv, "dFfg:hpqsvZz:")) != -1) { | 	while ((opt = getopt(argc, argv, "dFfg:hpqrsvZz:")) != -1) { | ||||||
| 		switch (opt) { | 		switch (opt) { | ||||||
| 			case '?': | 			case '?': | ||||||
| 				print_usage(); | 				print_usage(); | ||||||
| @@ -78,6 +78,9 @@ void parse_options(int argc, char **argv) { | |||||||
| 			case 'q': | 			case 'q': | ||||||
| 				_options.quiet = 1; | 				_options.quiet = 1; | ||||||
| 				break; | 				break; | ||||||
|  | 			case 'r': | ||||||
|  | 				_options.recursive = 1; | ||||||
|  | 				break; | ||||||
| 			case 's': | 			case 's': | ||||||
| 				_options.scalemode = SCALE_FIT; | 				_options.scalemode = SCALE_FIT; | ||||||
| 				break; | 				break; | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								sxiv.1
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								sxiv.1
									
									
									
									
									
								
							| @@ -3,7 +3,7 @@ | |||||||
| sxiv \- Simple (or small or suckless) X Image Viewer | sxiv \- Simple (or small or suckless) X Image Viewer | ||||||
| .SH SYNOPSIS | .SH SYNOPSIS | ||||||
| .B sxiv | .B sxiv | ||||||
| .RB [ \-dFfhpqsvZ ] | .RB [ \-dFfhpqrsvZ ] | ||||||
| .RB [ \-g | .RB [ \-g | ||||||
| .IR GEOMETRY ] | .IR GEOMETRY ] | ||||||
| .RB [ \-z | .RB [ \-z | ||||||
| @@ -41,6 +41,9 @@ Pixelize images, i.e. turn off anti-aliasing. | |||||||
| .B \-q | .B \-q | ||||||
| Be quiet, disable warnings to standard error stream. | Be quiet, disable warnings to standard error stream. | ||||||
| .TP | .TP | ||||||
|  | .B \-r | ||||||
|  | Search the given directories recursively for images to view. | ||||||
|  | .TP | ||||||
| .B \-s | .B \-s | ||||||
| Scale all images to fit into window. | Scale all images to fit into window. | ||||||
| .TP | .TP | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user