void init_parse_options(int argc, char **argv) { /* TODO: sort these to match declaration of __fehoptions */ /* For setting the command hint on X windows */ cmdargc = argc; cmdargv = argv; /* Set default options */ memset(&opt, 0, sizeof(fehoptions)); opt.display = 1; opt.aspect = 1; opt.slideshow_delay = 0.0; opt.magick_timeout = -1; opt.thumb_w = 60; opt.thumb_h = 60; opt.thumb_redraw = 10; opt.menu_font = estrdup(DEFAULT_MENU_FONT); opt.font = NULL; opt.menu_bg = estrdup(PREFIX "/share/feh/images/menubg_default.png"); opt.max_height = opt.max_width = UINT_MAX; opt.start_list_at = NULL; opt.jump_on_resort = 1; opt.screen_clip = 1; #ifdef HAVE_LIBXINERAMA /* if we're using xinerama, then enable it by default */ opt.xinerama = 1; #endif /* HAVE_LIBXINERAMA */ feh_getopt_theme(argc, argv); D(("About to check for theme configuration\n")); feh_check_theme_options(argv); D(("About to parse commandline options\n")); /* Parse the cmdline args */ feh_parse_option_array(argc, argv, 1); /* If we have a filelist to read, do it now */ if (opt.filelistfile) { /* joining two reverse-sorted lists in this manner works nicely for us here, as files specified on the commandline end up at the *end* of the combined filelist, in the specified order. */ D(("About to load filelist from file\n")); filelist = gib_list_cat(filelist, feh_read_filelist(opt.filelistfile)); } D(("Options parsed\n")); filelist_len = gib_list_length(filelist); if (!filelist_len) show_mini_usage(); check_options(); feh_prepare_filelist(); return; }
void feh_prepare_filelist(void) { if (opt.list || opt.customlist || (opt.sort > SORT_FILENAME) || opt.preload) { /* For these sort options, we have to preload images */ filelist = feh_file_info_preload(filelist); if (!gib_list_length(filelist)) show_mini_usage(); } D(3, ("sort mode requested is: %d\n", opt.sort)); switch (opt.sort) { case SORT_NONE: if (opt.randomize) { /* Randomize the filename order */ filelist = gib_list_randomize(filelist); } else if (!opt.reverse) { /* Let's reverse the list. Its back-to-front right now ;) */ filelist = gib_list_reverse(filelist); } break; case SORT_NAME: filelist = gib_list_sort(filelist, feh_cmp_name); break; case SORT_FILENAME: filelist = gib_list_sort(filelist, feh_cmp_filename); break; case SORT_WIDTH: filelist = gib_list_sort(filelist, feh_cmp_width); break; case SORT_HEIGHT: filelist = gib_list_sort(filelist, feh_cmp_height); break; case SORT_PIXELS: filelist = gib_list_sort(filelist, feh_cmp_pixels); break; case SORT_SIZE: filelist = gib_list_sort(filelist, feh_cmp_size); break; case SORT_FORMAT: filelist = gib_list_sort(filelist, feh_cmp_format); break; default: break; } /* no point reversing a random list */ if (opt.reverse && (opt.sort != SORT_NONE)) { D(3, ("Reversing filelist as requested\n")); filelist = gib_list_reverse(filelist); } return; }
int main(int argc, char *argv[]) { int argc_offset; int num_of_files; char* key = NULL; argc_offset = parse_options(argc, argv); if (argc_offset == argc) { show_mini_usage(); exit(EXIT_FAILURE); } if (!stdin_mode) { key = argv[argc_offset]; argc_offset++; } num_of_files = argc - argc_offset; if (num_of_files < 1) { show_mini_usage(); exit(EXIT_FAILURE); } if (stdin_mode) { char cmd[INPUT_STR_LEN_MAX]; while (fgets(cmd, (int)sizeof(cmd), stdin)) { cmd[strlen(cmd) - 1] = '\0'; /* delete '\n' */ search_all_files(argv + argc_offset, num_of_files, cmd); } } else { search_all_files(argv + argc_offset, num_of_files, key); } assert(sa_memory_leak_check()); return 0; }
void init_slideshow_mode(void) { winwidget w = NULL; int success = 0; char *s = NULL; gib_list *l = filelist, *last = NULL; feh_file *file = NULL; for (; l && opt.start_list_at; l = l->next) { if (!strcmp(opt.start_list_at, FEH_FILE(l->data)->filename)) { opt.start_list_at = NULL; break; } } if (opt.start_list_at) eprintf("--start-at %s: File not found in filelist", opt.start_list_at); mode = "slideshow"; for (; l; l = l->next) { file = FEH_FILE(l->data); if (last) { filelist = feh_file_remove_from_list(filelist, last); last = NULL; } current_file = l; s = slideshow_create_name(file, NULL); if ((w = winwidget_create_from_file(l, s, WIN_TYPE_SLIDESHOW)) != NULL) { free(s); success = 1; winwidget_show(w); if (opt.slideshow_delay > 0.0) feh_add_timer(cb_slide_timer, w, opt.slideshow_delay, "SLIDE_CHANGE"); if (opt.reload > 0) feh_add_unique_timer(cb_reload_timer, w, opt.reload); break; } else { free(s); last = l; } } if (!success) show_mini_usage(); return; }
void init_slideshow_mode(void) { winwidget w = NULL; int success = 0; gib_list *l = filelist, *last = NULL; /* * In theory, --start-at FILENAME is simple: Look for a file called * FILENAME, start the filelist there, done. * * In practice, there are cases where this isn't sufficient. For instance, * a user running 'feh --start-at hello.jpg /tmp' will expect feh to start * at /tmp/hello.jpg, as if they had used * 'feh --start-at /tmp/hello.jpg /tmp'. Similarly, XDG Desktop files * may lead to the invocation 'feh --start-at /tmp/hello.jpg .' in /tmp, * expecting the behaviour of 'feh --start-at ./hello.jpg .'. * * Since a good user experience is not about being technically correct, but * about delivering the expected behaviour, we do some fuzzy matching * here. In the worst case, this will cause --start-at to start at the * wrong file. */ // Try finding an exact filename match first for (; l && opt.start_list_at; l = l->next) { if (!strcmp(opt.start_list_at, FEH_FILE(l->data)->filename)) { opt.start_list_at = NULL; break; } } /* * If it didn't work (opt.start_list_at is still set): Fall back to * comparing just the filenames without directory prefixes. This may lead * to false positives, but for now that's just the way it is. */ if (opt.start_list_at) { char *current_filename; char *start_at_filename = strrchr(opt.start_list_at, '/'); if (start_at_filename) { start_at_filename++; // We only care about the part after the '/' } else { start_at_filename = opt.start_list_at; } for (l = filelist; l && opt.start_list_at; l = l->next) { current_filename = strrchr(FEH_FILE(l->data)->filename, '/'); if (current_filename) { current_filename++; // We only care about the part after the '/' } else { current_filename = FEH_FILE(l->data)->filename; } if (!strcmp(start_at_filename, current_filename)) { opt.start_list_at = NULL; break; } } } // If that didn't work either, we're out of luck. if (opt.start_list_at) eprintf("--start-at %s: File not found in filelist", opt.start_list_at); if (!opt.title) opt.title = PACKAGE " [%u of %l] - %f"; mode = "slideshow"; for (; l; l = l->next) { if (last) { filelist = feh_file_remove_from_list(filelist, last); last = NULL; } current_file = l; if ((w = winwidget_create_from_file(l, WIN_TYPE_SLIDESHOW)) != NULL) { success = 1; winwidget_show(w); if (opt.slideshow_delay > 0.0) feh_add_timer(cb_slide_timer, w, opt.slideshow_delay, "SLIDE_CHANGE"); if (opt.reload > 0) feh_add_unique_timer(cb_reload_timer, w, opt.reload); break; } else { last = l; } } if (!success) show_mini_usage(); return; }
static int parse_options(int argc, char **argv) { int digit_args_val = 0; while (1) { int ch = getopt_long(argc, argv, short_options, long_options, NULL); if (ch == EOF) { break; } switch (ch) { case 'h': show_usage(); exit(EXIT_FAILURE); break; case 'i': ignore_case_mode = 1; break; case 'r': regex_mode = 1; break; case 's': stdin_mode = 1; break; case 'A': if (ck_atoi(optarg, &after_context)) { fprintf(stderr, "invalid context length argument\n"); exit(EXIT_FAILURE); } break; case 'B': if (ck_atoi(optarg, &before_context)) { fprintf(stderr, "invalid context length argument\n"); exit(EXIT_FAILURE); } break; case 'C': if (optarg) { if (ck_atoi(optarg, &before_context)) { fprintf(stderr, "invalid context length argument\n"); exit(EXIT_FAILURE); } after_context = before_context; } else { before_context = 2; after_context = 2; } break; case 'd': sa_set_debug_mode(1); break; case 't': tag_mode = 1; parse_tags(optarg); break; case 'a': array_file_mode = 1; strcpy(array_file_name, optarg); break; case 'k': keyword_emphasis_mode = 1; break; case 'u': uniq_mode = sort_mode = 1; break; case 'S': sort_mode = 1; break; case 'c': count_only_mode = 1; break; case 'v': printf("sass of SUFARY %s\n", VERSION); printf("Copyright (C) 1997-1999 YAMASHITA Tatuo All rights reserved.\n"); exit(EXIT_FAILURE); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': digit_args_val = 10 * digit_args_val + ch - '0'; before_context = digit_args_val; after_context = digit_args_val; break; default: show_mini_usage(); exit(EXIT_FAILURE); } } return optind; }