void cb_reload_timer(void *data) { gib_list *l; char *current_filename; winwidget w = (winwidget) data; /* save the current filename for refinding it in new list */ current_filename = estrdup(FEH_FILE(current_file->data)->filename); for (l = filelist; l; l = l->next) { feh_file_free(l->data); l->data = NULL; } gib_list_free_and_data(filelist); filelist = NULL; filelist_len = 0; current_file = NULL; /* rebuild filelist from original_file_items */ if (gib_list_length(original_file_items) > 0) for (l = gib_list_last(original_file_items); l; l = l->prev) add_file_to_filelist_recursively(l->data, FILELIST_FIRST); else if (!opt.filelistfile && !opt.bgmode) add_file_to_filelist_recursively(".", FILELIST_FIRST); if (!(filelist_len = gib_list_length(filelist))) { eprintf("No files found to reload."); } /* find the previously current file */ for (l = filelist; l; l = l->next) if (strcmp(FEH_FILE(l->data)->filename, current_filename) == 0) { current_file = l; break; } free(current_filename); filelist = gib_list_first(gib_list_reverse(filelist)); if (!current_file) current_file = filelist; w->file = current_file; /* reset window name in case of current file order, * filename, or filelist_length has changed. */ current_filename = slideshow_create_name(FEH_FILE(current_file->data), w); winwidget_rename(w, current_filename); free(current_filename); feh_reload_image(w, 1, 0); if (opt.reload) feh_add_unique_timer(cb_reload_timer, w, opt.reload); return; }
/* Recursive */ void add_file_to_filelist_recursively(char *origpath, unsigned char level) { struct stat st; char *path; if (!origpath) return; path = estrdup(origpath); D(4, ("file is %s\n", path)); if (level == FILELIST_FIRST) { /* First time through, sort out pathname */ int len = 0; len = strlen(path); if (path[len - 1] == '/') path[len - 1] = '\0'; if ((!strncmp(path, "http://", 7)) || (!strncmp(path, "https://", 8)) || (!strncmp(path, "ftp://", 6))) { /* Its a url */ D(3, ("Adding url %s to filelist\n", path)); filelist = gib_list_add_front(filelist, feh_file_new(path)); /* We'll download it later... */ free(path); return; } else if (opt.filelistfile) { char *newpath = feh_absolute_path(path); free(path); path = newpath; } } errno = 0; if (stat(path, &st)) { /* Display useful error message */ switch (errno) { case ENOENT: case ENOTDIR: if (!opt.quiet) weprintf("%s does not exist - skipping", path); break; case ELOOP: if (!opt.quiet) weprintf("%s - too many levels of symbolic links - skipping", path); break; case EACCES: if (!opt.quiet) weprintf("you don't have permission to open %s - skipping", path); break; default: if (!opt.quiet) weprintf("couldn't open %s", path); break; } free(path); return; } if ((S_ISDIR(st.st_mode)) && (level != FILELIST_LAST)) { struct dirent *de; DIR *dir; D(4, ("It is a directory\n")); if ((dir = opendir(path)) == NULL) { if (!opt.quiet) weprintf("couldn't open directory %s:", path); free(path); return; } de = readdir(dir); while (de != NULL) { if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..")) { char *newfile; newfile = estrjoin("", path, "/", de->d_name, NULL); /* This ensures we go down one level even if not fully recursive - this way "feh some_dir" expands to some_dir's contents */ if (opt.recursive) add_file_to_filelist_recursively(newfile, FILELIST_CONTINUE); else add_file_to_filelist_recursively(newfile, FILELIST_LAST); free(newfile); } de = readdir(dir); } closedir(dir); } else if (S_ISREG(st.st_mode)) { D(5, ("Adding regular file %s to filelist\n", path)); filelist = gib_list_add_front(filelist, feh_file_new(path)); } free(path); return; }
static void feh_parse_option_array(int argc, char **argv, int finalrun) { int discard; static char stropts[] = "a:A:b:B:cC:dD:e:E:f:Fg:GhH:iIj:J:kK:lL:mM:nNo:O:pPqrR:sS:tT:uUvVwW:xXy:YzZ" ".@:^:~:):|:+:<:>:"; /* (*name, has_arg, *flag, val) See: struct option in getopts.h */ static struct option lopts[] = { {"menu-bg" , 1, 0, ')'}, {"debug" , 0, 0, '+'}, {"scale-down" , 0, 0, '.'}, {"max-dimension" , 1, 0, '<'}, {"min-dimension" , 1, 0, '>'}, {"title-font" , 1, 0, '@'}, {"action" , 1, 0, 'A'}, {"image-bg" , 1, 0, 'B'}, {"fontpath" , 1, 0, 'C'}, {"slideshow-delay",1, 0, 'D'}, {"thumb-height" , 1, 0, 'E'}, {"full-screen" , 0, 0, 'F'}, /* deprecated */ {"fullscreen" , 0, 0, 'F'}, {"draw-actions" , 0, 0, 'G'}, {"limit-height" , 1, 0, 'H'}, {"fullindex" , 0, 0, 'I'}, {"thumb-redraw" , 1, 0, 'J'}, {"caption-path" , 1, 0, 'K'}, {"customlist" , 1, 0, 'L'}, {"menu-font" , 1, 0, 'M'}, {"no-menus" , 0, 0, 'N'}, {"output-only" , 1, 0, 'O'}, {"cache-thumbnails", 0, 0, 'P'}, {"reload" , 1, 0, 'R'}, {"sort" , 1, 0, 'S'}, {"theme" , 1, 0, 'T'}, {"loadable" , 0, 0, 'U'}, {"verbose" , 0, 0, 'V'}, {"limit-width" , 1, 0, 'W'}, {"ignore-aspect" , 0, 0, 'X'}, {"hide-pointer" , 0, 0, 'Y'}, {"auto-zoom" , 0, 0, 'Z'}, {"title" , 1, 0, '^'}, {"alpha" , 1, 0, 'a'}, {"bg" , 1, 0, 'b'}, {"collage" , 0, 0, 'c'}, {"draw-filename" , 0, 0, 'd'}, {"font" , 1, 0, 'e'}, {"filelist" , 1, 0, 'f'}, {"geometry" , 1, 0, 'g'}, {"help" , 0, 0, 'h'}, {"index" , 0, 0, 'i'}, {"output-dir" , 1, 0, 'j'}, {"keep-http" , 0, 0, 'k'}, {"list" , 0, 0, 'l'}, {"montage" , 0, 0, 'm'}, {"reverse" , 0, 0, 'n'}, {"output" , 1, 0, 'o'}, {"preload" , 0, 0, 'p'}, {"quiet" , 0, 0, 'q'}, {"recursive" , 0, 0, 'r'}, {"stretch" , 0, 0, 's'}, {"thumbnails" , 0, 0, 't'}, {"unloadable" , 0, 0, 'u'}, {"version" , 0, 0, 'v'}, {"multiwindow" , 0, 0, 'w'}, {"borderless" , 0, 0, 'x'}, {"thumb-width" , 1, 0, 'y'}, {"randomize" , 0, 0, 'z'}, {"start-at" , 1, 0, '|'}, {"thumb-title" , 1, 0, '~'}, {"bg-tile" , 0, 0, 200}, {"bg-center" , 0, 0, 201}, {"bg-scale" , 0, 0, 202}, {"zoom" , 1, 0, 205}, {"no-screen-clip", 0, 0, 206}, {"index-info" , 1, 0, 207}, {"magick-timeout", 1, 0, 208}, {"action1" , 1, 0, 209}, {"action2" , 1, 0, 210}, {"action3" , 1, 0, 211}, {"action4" , 1, 0, 212}, {"action5" , 1, 0, 213}, {"action6" , 1, 0, 214}, {"action7" , 1, 0, 215}, {"action8" , 1, 0, 216}, {"action9" , 1, 0, 217}, {"bg-fill" , 0, 0, 218}, {"bg-max" , 0, 0, 219}, {"no-jump-on-resort", 0, 0, 220}, #ifdef HAVE_LIBEXIF {"draw-exif" , 0, 0, 223}, #endif {"cycle-once" , 0, 0, 224}, {"no-xinerama" , 0, 0, 225}, {"draw-tinted" , 0, 0, 229}, {"info" , 1, 0, 234}, {"force-aliasing", 0, 0, 235}, {"no-fehbg" , 0, 0, 236}, {"keep-zoom-vp" , 0, 0, 237}, {"scroll-step" , 1, 0, 238}, {"xinerama-index", 1, 0, 239}, {0, 0, 0, 0} }; int optch = 0, cmdx = 0; while ((optch = getopt_long(argc, argv, stropts, lopts, &cmdx)) != EOF) { D(("Got option, getopt calls it %d, or %c\n", optch, optch)); switch (optch) { case 0: break; case ')': free(opt.menu_bg); opt.menu_bg = estrdup(optarg); weprintf("The --menu-bg option is deprecated and will be removed by 2012"); break; case '+': opt.debug = 1; break; case '<': XParseGeometry(optarg, &discard, &discard, &opt.max_width, &opt.max_height); if (opt.max_width == 0) opt.max_width = UINT_MAX; if (opt.max_height == 0) opt.max_height = UINT_MAX; break; case '>': XParseGeometry(optarg, &discard, &discard, &opt.min_width, &opt.min_height); break; case '.': opt.scale_down = 1; break; case '@': opt.title_font = estrdup(optarg); break; case 'A': opt.actions[0] = estrdup(optarg); break; case 'B': if (!strcmp(optarg, "checks")) opt.image_bg = IMAGE_BG_CHECKS; else if (!strcmp(optarg, "white")) opt.image_bg = IMAGE_BG_WHITE; else if (!strcmp(optarg, "black")) opt.image_bg = IMAGE_BG_BLACK; else weprintf("Unknown argument to --image-bg: %s", optarg); break; case 'C': D(("adding fontpath %s\n", optarg)); imlib_add_path_to_font_path(optarg); break; case 'D': opt.slideshow_delay = atof(optarg); if (opt.slideshow_delay < 0.0) { opt.slideshow_delay *= (-1); opt.paused = 1; } break; case 'E': opt.thumb_h = atoi(optarg); break; case 'F': opt.full_screen = 1; break; case 'G': opt.draw_actions = 1; break; case 'H': opt.limit_h = atoi(optarg); break; case 'I': opt.index = 1; opt.index_info = estrdup("%n\n%S\n%wx%h"); break; case 'J': opt.thumb_redraw = atoi(optarg); break; case 'K': opt.caption_path = estrdup(optarg); break; case 'L': opt.customlist = estrdup(optarg); opt.display = 0; break; case 'M': free(opt.menu_font); opt.menu_font = estrdup(optarg); break; case 'N': opt.no_menus = 1; break; case 'O': opt.output = 1; opt.output_file = estrdup(optarg); opt.display = 0; break; case 'P': opt.cache_thumbnails = 1; break; case 'R': opt.reload = atof(optarg); break; case 'S': if (!strcasecmp(optarg, "name")) opt.sort = SORT_NAME; else if (!strcasecmp(optarg, "filename")) opt.sort = SORT_FILENAME; else if (!strcasecmp(optarg, "mtime")) opt.sort = SORT_MTIME; else if (!strcasecmp(optarg, "width")) opt.sort = SORT_WIDTH; else if (!strcasecmp(optarg, "height")) opt.sort = SORT_HEIGHT; else if (!strcasecmp(optarg, "pixels")) opt.sort = SORT_PIXELS; else if (!strcasecmp(optarg, "size")) opt.sort = SORT_SIZE; else if (!strcasecmp(optarg, "format")) opt.sort = SORT_FORMAT; else { weprintf("Unrecognised sort mode \"%s\". Defaulting to " "sort by filename", optarg); opt.sort = SORT_FILENAME; } if (opt.randomize) { weprintf("commandline contains --randomize and --sort. " "--randomize has been unset"); opt.randomize = 0; } break; case 'T': theme = estrdup(optarg); break; case 'U': opt.loadables = 1; opt.display = 0; break; case 'V': opt.verbose = 1; break; case 'W': opt.limit_w = atoi(optarg); break; case 'X': opt.aspect = 0; break; case 'Y': opt.hide_pointer = 1; break; case 'Z': opt.zoom_mode = ZOOM_MODE_MAX; break; case '^': opt.title = estrdup(optarg); break; case 'a': opt.alpha = 1; opt.alpha_level = 255 - atoi(optarg); break; case 'b': opt.bg = 1; opt.bg_file = estrdup(optarg); break; case 'c': opt.collage = 1; break; case 'd': opt.draw_filename = 1; break; case 'e': opt.font = estrdup(optarg); break; case 'f': if (!strcmp(optarg, "-")) opt.filelistfile = estrdup("/dev/stdin"); else opt.filelistfile = estrdup(optarg); break; case 'g': opt.geom_flags = XParseGeometry(optarg, &opt.geom_x, &opt.geom_y, &opt.geom_w, &opt.geom_h); break; case 'h': show_usage(); break; case 'i': opt.index = 1; opt.index_info = estrdup("%n"); break; case 'j': opt.output_dir = estrdup(optarg); break; case 'k': opt.keep_http = 1; break; case 'l': opt.list = 1; opt.display = 0; break; case 'm': opt.index = 1; break; case 'n': opt.reverse = 1; break; case 'o': opt.output = 1; opt.output_file = estrdup(optarg); break; case 'p': opt.preload = 1; break; case 'q': opt.quiet = 1; break; case 'r': opt.recursive = 1; break; case 's': opt.stretch = 1; break; case 't': opt.thumbs = 1; opt.index_info = estrdup("%n"); break; case 'u': opt.unloadables = 1; opt.display = 0; break; case 'v': show_version(); break; case 'w': opt.multiwindow = 1; break; case 'x': opt.borderless = 1; break; case 'y': opt.thumb_w = atoi(optarg); break; case 'z': opt.randomize = 1; if (opt.sort != SORT_NONE) { weprintf("commandline contains --sort and --randomize. " "--sort has been unset"); opt.sort = SORT_NONE; } break; case '|': opt.start_list_at = estrdup(optarg); break; case '~': opt.thumb_title = estrdup(optarg); break; case 200: opt.bgmode = BG_MODE_TILE; break; case 201: opt.bgmode = BG_MODE_CENTER; break; case 202: opt.bgmode = BG_MODE_SCALE; break; case 205: if (!strcmp("fill", optarg)) opt.zoom_mode = ZOOM_MODE_FILL; else if (!strcmp("max", optarg)) opt.zoom_mode = ZOOM_MODE_MAX; else opt.default_zoom = atoi(optarg); break; case 206: opt.screen_clip = 0; break; case 207: opt.index_info = estrdup(optarg); break; case 208: opt.magick_timeout = atoi(optarg); break; case 209: opt.actions[1] = estrdup(optarg); break; case 210: opt.actions[2] = estrdup(optarg); break; case 211: opt.actions[3] = estrdup(optarg); break; case 212: opt.actions[4] = estrdup(optarg); break; case 213: opt.actions[5] = estrdup(optarg); break; case 214: opt.actions[6] = estrdup(optarg); break; case 215: opt.actions[7] = estrdup(optarg); break; case 216: opt.actions[8] = estrdup(optarg); break; case 217: opt.actions[9] = estrdup(optarg); break; case 218: opt.bgmode = BG_MODE_FILL; break; case 219: opt.bgmode = BG_MODE_MAX; break; case 220: opt.jump_on_resort = 0; break; #ifdef HAVE_LIBEXIF case 223: opt.draw_exif = 1; break; #endif case 224: opt.cycle_once = 1; break; case 225: opt.xinerama = 0; break; case 229: opt.text_bg = TEXT_BG_TINTED; break; case 234: opt.info_cmd = estrdup(optarg); if (opt.info_cmd[0] == ';') opt.info_cmd++; else opt.draw_info = 1; break; case 235: opt.force_aliasing = 1; break; case 236: opt.no_fehbg = 1; break; case 237: opt.keep_zoom_vp = 1; break; case 238: opt.scroll_step = atoi(optarg); break; case 239: opt.xinerama_index = atoi(optarg); break; default: break; } } /* Now the leftovers, which must be files */ if (optind < argc) { while (optind < argc) { if (opt.reload) original_file_items = gib_list_add_front(original_file_items, estrdup(argv[optind])); /* If recursive is NOT set, but the only argument is a directory name, we grab all the files in there, but not subdirs */ add_file_to_filelist_recursively(argv[optind++], FILELIST_FIRST); } } else if (finalrun && !opt.filelistfile && !opt.bgmode) add_file_to_filelist_recursively(".", FILELIST_FIRST); /* So that we can safely be called again */ optind = 0; return; }