--- feh-1.10.1.old/config.mk +++ feh-1.10.1/config.mk @@ -2,13 +2,13 @@ VERSION ?= 1.10.1 # Prefix for all installed files -PREFIX ?= /usr/local +PREFIX ?= __META_PREFIX__ # Directories for manuals, executables, docs, data, etc. main_dir = ${DESTDIR}${PREFIX} -man_dir = ${main_dir}/share/man +man_dir = ${main_dir}/man bin_dir = ${main_dir}/bin -doc_dir = ${main_dir}/share/doc/feh +doc_dir = ${main_dir}/doc/feh image_dir = ${main_dir}/share/feh/images font_dir = ${main_dir}/share/feh/fonts @@ -17,8 +17,8 @@ CFLAGS += -Wall -Wextra -pedantic # Comment these out if you don't have libxinerama -xinerama = -DHAVE_LIBXINERAMA -xinerama_ld = -lXinerama +# xinerama = -DHAVE_LIBXINERAMA +# xinerama_ld = -lXinerama # Uncomment this for debug mode # (Use feh -+ or feh --debug to see debug output) --- feh-1.10.1.old/src/feh_png.c +++ feh-1.10.1/src/feh_png.c @@ -66,7 +66,7 @@ return hash; } - if (setjmp(png_ptr->jmpbuf)) { + if (setjmp(png_jmpbuf (png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(fp); return hash; @@ -124,7 +124,7 @@ return 0; } - if (setjmp(png_ptr->jmpbuf)) { + if (setjmp(png_jmpbuf (png_ptr))) { fclose(fp); png_destroy_write_struct(&png_ptr, &info_ptr); png_destroy_info_struct(png_ptr, &info_ptr); --- feh-1.10.1.old/src/filelist.c +++ feh-1.10.1/src/filelist.c @@ -81,6 +81,7 @@ info->has_alpha = 0; info->format = NULL; info->extension = NULL; + info->mtime = 0; return(info); } @@ -316,8 +317,8 @@ file->info->pixels = file->info->width * file->info->height; file->info->format = estrdup(gib_imlib_image_format(im1)); - - file->info->size = st.st_size; + file->info->size = st.st_size; + file->info->mtime = st.st_mtime; if (need_free && im1) gib_imlib_free_image_and_decache(im1); @@ -359,6 +360,18 @@ return(strcmp(FEH_FILE(file1)->info->format, FEH_FILE(file2)->info->format)); } +static int longcmp (long n1, long n2) +{ + if (n1 == n2) return (0); + return ((n1 < n2) ? -1 : 1); +} + +int feh_cmp_mtime (void *file1, void *file2) +{ + return (longcmp (FEH_FILE(file1)->info->mtime, + FEH_FILE(file2)->info->mtime)); +} + void feh_prepare_filelist(void) { if (opt.list || opt.customlist || (opt.sort > SORT_FILENAME) @@ -401,7 +414,8 @@ case SORT_FORMAT: filelist = gib_list_sort(filelist, feh_cmp_format); break; - default: + case SORT_MTIME: + filelist = gib_list_sort(filelist, feh_cmp_mtime); break; } --- feh-1.10.1.old/src/filelist.h +++ feh-1.10.1/src/filelist.h @@ -43,16 +43,18 @@ unsigned char has_alpha; char *format; char *extension; + long mtime; }; #define FEH_FILE(l) ((feh_file *) l) enum filelist_recurse { FILELIST_FIRST, FILELIST_CONTINUE, FILELIST_LAST }; -enum sort_type { SORT_NONE, SORT_NAME, SORT_FILENAME, SORT_WIDTH, - SORT_HEIGHT, - SORT_PIXELS, - SORT_SIZE, SORT_FORMAT +enum sort_type +{ + SORT_NONE , SORT_NAME , SORT_FILENAME , SORT_WIDTH , + SORT_HEIGHT , SORT_PIXELS , SORT_SIZE , SORT_FORMAT , + SORT_MTIME }; feh_file *feh_file_new(char *filename); @@ -79,6 +81,7 @@ int feh_cmp_pixels(void *file1, void *file2); int feh_cmp_size(void *file1, void *file2); int feh_cmp_format(void *file1, void *file2); +int feh_cmp_mtime(void *file1, void *file2); extern gib_list *filelist; extern int filelist_len; --- feh-1.10.1.old/src/help.raw +++ feh-1.10.1/src/help.raw @@ -1,8 +1,13 @@ " PACKAGE " version " VERSION " -Usage : " PACKAGE " [options] +Usage: " PACKAGE " [options] - This is just a short option summary. Please consult the manual for details. +This is just a short option summary. Please consult the manual for de- +tails. + +NOTE: This is a non-standard version of feh. There is no support. Do +not send bug reports to the original authors, as they are not re- +sponsible for this version. OPTIONS -h, --help Show help and exit @@ -13,44 +18,119 @@ -_, --rcfile FILE Use FILE to parse themes and options from -r, --recursive Recursively expand any directories in FILE to the content of those directories. (Take it easy) - -z, --randomize Randomize the filelist + -:, --randomize Randomize the filelist --no-jump-on-resort Don't jump to the first image when the filelist is resorted -g, --geometry STRING Limit the window size to STRING, like \"640x480\" -f, --filelist FILE Load/save images from/to the FILE filelist -|, --start-at POSITION Start at POSITION in the filelist - -p, --preload Remove unlaodable files from the internal filelist - before attempting to display anything - -., --scale-down Automatically scale down images to fit the screen - size - -F, --fullscreen Make the window full screen - -Z, --auto-zoom Zoom picture to screen size in full screen mode + -p, --preload Remove unloadable files from the internal + filelist before attempting to display any- + thing + -., --scale-down Automatically scale down images to fit the + screen size + -F Don't use fullscreen mode + -Z, --auto-zoom Zoom picture to screen size in fullscreen + mode; is affected by --stretch --zoom PERCENT Zooms images by a PERCENT, when in full screen - mode or when window geometry is fixed. If combined - with --auto-zoom, zooming will be limited to the - the size. + mode or when window geometry is fixed. If com- + bined with --auto-zoom, zooming will be limit- + ed to the size. -w, --multiwindow Open all files at once, one window per image -x, --borderless Create borderless windows - -d, --draw-filename Show the filename in the image window + + -d, --draw-filename Affects a filename-display feature. By de- + fault, this version of feh starts in full- + screen mode and draws the current filename in + the top-left corner of the display. If -F is + specified, both features are disabled. To use + non-fullscreen mode with filename drawing en- + abled, specify -F -d. To disable filename + drawing without disabling fullscreen mode, + specify -d without -F. Note: -d only affects + the filename that's drawn in the output win- + dow. If fullscreen mode is disabled, file- + names may be displayed in feh's title bar, + whether or not -d is used. + -^, --title TITLE Set window title (see FORMAT SPECIFIERS) -D, --slideshow-delay NUM Set delay between automatically changing slides --cycle-once Exit after one loop through the slideshow -R, --reload NUM Reload images after NUM seconds -Q, --builtin Use builtin http client instead of wget -k, --keep-http Keep local copies when viewing HTTP/FTP files - -K, --caption-path PATH Path to caption directory, enables caption display + + -K, --caption-path PATH Path to caption directory, enables caption + display + -j, --output-dir With -k: Output directory for saved files - -l, --list list mode: ls-style output with image information - -L, --customlist FORMAT list mode with custom output, see FORMAT SPECIFIERS + + -l, --list list mode: ls-style output with image infor- + mation + + -L, --customlist FORMAT list mode with custom output, see FORMAT + SPECIFIERS + -U, --loadable List all loadable files. No image display -u, --unloadable List all unloadable files. No image display - -S, --sort SORT_TYPE Sort files by: - name, filename, width, height, pixels, size or format - -n, --reverse Reverse sort order + + -S, --sort SORT_TYPE Sort the image list. Supported sort modes in- + clude: name, filename, width, height, pixels, + size, format, mtime + + Note: mtime is a local addition. --sort mtime + shows images from oldest to newest, based on + modification time. Standalone --oldest and + --newest switches are also provided; see the + following notes. + + For sort modes other than name or filename, a + preload pass is required. This adds a delay + proportional to the number of images in the + list. + + -n, --reverse Reverses the selected sort order. For exam- + ple: To display files from newest to oldest, + use --sort mtime --reverse or -nSmtime. To + display images from widest to thinnest, use + --sort width --reverse or -nSwidth. + + --oldest, --newest --oldest shows images from oldest to newest, + based on modification time. --newest shows + images from newest to oldest. These switches + are aliases for --sort mtime and --sort mtime + --reverse, respectively. + + --thinnest, --fattest, --widest + --thinnest shows images from thinnest to wid- + est. --fattest and --widest are interchange- + able. These two switches show images from + widest to thinnest. --thinnest is an alias + for --sort width and the other two switches + are aliases for --sort width --reverse. + + --shortest, --tallest + --shortest shows images from shortest to tal- + lest. --tallest shows images from tallest to + shortest. These two switches are aliases for + --sort height and --sort height --reverse, + respectively. + + --smallest, --biggest, --largest + --smallest shows images from smallest to lar- + gest, based on size in bytes. --biggest and + --largest are interchangeable. These two swi- + tches show images from largest to smallest. + --smallest is an alias for --sort size and + the other two switches are aliases for --sort + size --reverse + -A, --action ACTION Specify action to perform when pressing . Executed by /bin/sh, may contain FORMAT SPECIFIERS --action[1-9] Extra actions triggered by pressing keys <1>to <9> - --action-hold-slide Do not change to next image after running an action + --action-hold-slide Do not change to next image after running an + action + -G, --draw-actions Show the defined actions in the image window -m, --montage Enable montage mode -c, --collage Montage mode with randomly distributed thumbnails @@ -151,10 +231,20 @@ \\n newline KEYS - p, , Go to previous slide - n, , Go to next slide - r Reload image - v Toggle fullscreen + + Home, End Jump to first or last image + q, Q, Escape Quit the slideshow + z, Z Toggle Zoom mode + + p, P, , Go to previous image + PageUp Ditto + + n, N, , Go to next image + PageDn Ditto + + r, R Reload image (useful for webcams) + v, V Toggle fullscreen mode + m Show menu c Enable caption entry mode w Resize window to current image dimensions --- feh-1.10.1.old/src/keyevents.c +++ feh-1.10.1/src/keyevents.c @@ -83,9 +83,13 @@ feh_menu_select_parent(selected_menu); break; case XK_Down: + case XK_Page_Down: + case XK_KP_Page_Down: feh_menu_select_next(selected_menu, selected_item); break; case XK_Up: + case XK_Page_Up: + case XK_KP_Page_Up: feh_menu_select_prev(selected_menu, selected_item); break; case XK_Right: @@ -95,8 +99,6 @@ case XK_space: feh_menu_item_activate(selected_menu, selected_item); break; - default: - break; } return; @@ -173,19 +175,22 @@ else if (opt.slideshow) slideshow_change_image(winwid, SLIDE_NEXT); break; - case XK_Page_Up: - case XK_KP_Page_Up: - if (opt.slideshow) - slideshow_change_image(winwid, SLIDE_JUMP_BACK); - break; - case XK_Escape: - winwidget_destroy_all(); - break; - case XK_Page_Down: - case XK_KP_Page_Down: - if (opt.slideshow) - slideshow_change_image(winwid, SLIDE_JUMP_FWD); - break; + + case XK_Page_Up: + case XK_KP_Page_Up: + if (opt.slideshow) + slideshow_change_image(winwid, SLIDE_PREV); + break; + case XK_Page_Down: + case XK_KP_Page_Down: + if (opt.slideshow) + slideshow_change_image(winwid, SLIDE_NEXT); + break; + + case XK_Escape: + winwidget_destroy_all(); + break; + case XK_Delete: /* Holding ctrl gets you a filesystem deletion and removal from the * filelist. Just DEL gets you filelist removal only. */ @@ -319,8 +324,23 @@ case XK_KP_Begin: winwidget_render_image(winwid, 0, 1); break; - default: - break; + + case 'z': case 'Z': + if (winwid->zoom == 1) + { + opt.auto_zoom = 1; + feh_calc_needed_zoom +(&winwid->zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h); + } + else + { + opt.auto_zoom = 0; + winwid->zoom = 1; + } + + winwidget_render_image (winwid, opt.full_screen, 0); + winwidget_rerender_all (0, 1); + break; } if (len <= 0 || len > (int) sizeof(kbuf)) @@ -350,7 +370,7 @@ if (opt.slideshow) slideshow_change_image(winwid, SLIDE_PREV); break; - case 'z': + case ':': if (opt.slideshow) slideshow_change_image(winwid, SLIDE_RAND); break; @@ -448,8 +468,6 @@ else if (opt.verbose) weprintf("Cannot set RELOAD lower than 1 second."); break; - default: - break; } return; } --- feh-1.10.1.old/src/options.c +++ feh-1.10.1/src/options.c @@ -319,6 +319,9 @@ static void feh_parse_option_array(int argc, char **argv) { + char *cp; + int n; + static char stropts[] = "a:A:b:B:cC:dD:e:E:f:Fg:GhH:iIj:J:kK:lL:mM:nNo:O:pPqQrR:sS:tT:uUvVwW:xXy:YzZ" "0:1:2:4:5:8:9:.@:^:~:):|:_:+:"; @@ -337,14 +340,13 @@ {"stretch" , 0, 0, 's'}, {"multiwindow" , 0, 0, 'w'}, {"recursive" , 0, 0, 'r'}, - {"randomize" , 0, 0, 'z'}, + {"randomize" , 0, 0, ':'}, {"list" , 0, 0, 'l'}, {"quiet" , 0, 0, 'q'}, {"loadable" , 0, 0, 'U'}, {"unloadable" , 0, 0, 'u'}, {"no-menus" , 0, 0, 'N'}, - {"full-screen" , 0, 0, 'F'}, /* deprecated */ - {"fullscreen" , 0, 0, 'F'}, + {"normal-screen" , 0, 0, 'F'}, {"auto-zoom" , 0, 0, 'Z'}, {"ignore-aspect" , 0, 0, 'X'}, {"draw-filename" , 0, 0, 'd'}, @@ -358,6 +360,7 @@ {"draw-actions" , 0, 0, 'G'}, {"cache-thumbnails", 0, 0, 'P'}, {"cycle-once" , 0, 0, 224}, + {"no-xinerama" , 0, 0, 225}, {"no-rotate-ctrl-mask", 0, 0, 226}, {"no-blur-ctrl-mask", 0, 0, 227}, @@ -423,11 +426,48 @@ {"thumb-redraw" , 1, 0, 'J'}, {"info" , 1, 0, 234}, +//-------------------------------------------------------------------- +// Local additions. + + // Alias for --sort mtime + { "oldest" , 0, 0, 235 } , + // Alias for --sort mtime --reverse + { "newest" , 0, 0, 236 } , + // Alias for --sort width + { "thinnest" , 0, 0, 237 } , + // Note: "fattest" and "widest" are + // equivalent, so they're mapped to + // the same option code [228] + + // Alias for --sort width --reverse + { "fattest" , 0, 0, 238 } , + // Ditto + { "widest" , 0, 0, 238 } , + // Alias for --sort height + { "shortest" , 0, 0, 239 } , + // Alias for --sort height --reverse + { "tallest" , 0, 0, 240 } , + // Alias for --sort size + { "smallest" , 0, 0, 241 } , + // Note: "biggest" and "largest" are + // equivalent, so they're mapped to + // the same option code [232] + + // Alias for --sort size --reverse + { "biggest" , 0, 0, 242 } , + // Ditto + { "largest" , 0, 0, 242 } , + +//-------------------------------------------------------------------- + {0, 0, 0, 0} }; int optch = 0, cmdx = 0; int i = 0; + opt.draw_filename = 1; + opt.full_screen = 1; + /* Now to pass some optionarinos */ while ((optch = getopt_long(argc, argv, stropts, lopts, &cmdx)) != EOF) { D(("Got option, getopt calls it %d, or %c\n", optch, optch)); @@ -512,14 +552,15 @@ case 'r': opt.recursive = 1; break; - case 'z': + case ':': opt.randomize = 1; break; case 'd': - opt.draw_filename = 1; + opt.draw_filename = opt.draw_filename ? 0 : 1; break; case 'F': - opt.full_screen = 1; + opt.draw_filename = 0; + opt.full_screen = 0; break; case 'Z': opt.auto_zoom = 1; @@ -553,6 +594,8 @@ opt.sort = SORT_SIZE; else if (!strcasecmp(optarg, "format")) opt.sort = SORT_FORMAT; + else if (!strcasecmp(optarg, "mtime")) + opt.sort = SORT_MTIME; else { weprintf("Unrecognised sort mode \"%s\". Defaulting to " "sort by filename", optarg); @@ -772,10 +815,62 @@ case 234: opt.info_cmd = estrdup(optarg); break; - default: - break; - } - } + +//-------------------------------------------------------------------- +// Local additions. + + case 235: // --oldest = --sort mtime + opt.sort = SORT_MTIME; + break; + case 236: // --newest = --sort mtime --reverse + opt.sort = SORT_MTIME; + opt.reverse = 1; + break; + case 237: // --thinnest = --sort width + opt.sort = SORT_WIDTH; + break; + case 238: // --fattest or --widest + // = --sort width --reverse + opt.sort = SORT_WIDTH; + opt.reverse = 1; + break; + case 239: // --shortest = --sort height + opt.sort = SORT_HEIGHT; + break; + case 240: // --tallest = --sort height --reverse + opt.sort = SORT_HEIGHT; + opt.reverse = 1; + break; + case 241: // --smallest = --sort size + opt.sort = SORT_SIZE; + break; + case 242: // --biggest or --largest + // = --sort size --reverse + opt.sort = SORT_SIZE; + opt.reverse = 1; + break; + } + } + +//-------------------------------------------------------------------- + +// As of mid-2007, "imlib2" apparently lacks support for "gif" output +// files. Therefore, if the user specifies a "gif" output file, the +// old version of this program fails. As a workaround, the new ver- +// sion changes "gif" output files into "png" output files. + +// Note: It should be safe to modify the "opt.output_file" string +// here, as long as no attempt is made to write past the end of the +// associated storage space. + + if (((cp = opt.output_file) != NULL) && + ((n = strlen (cp)) > 4)) + { + cp = &cp [n - 3]; + if (!strcasecmp (cp, "gif")) strcpy (cp, "png"); + } + +//-------------------------------------------------------------------- /* Now the leftovers, which must be files */ if (optind < argc) { --- feh-1.10.1.old/src/slideshow.c +++ feh-1.10.1/src/slideshow.c @@ -455,6 +455,9 @@ void slideshow_save_image(winwidget win) { + char *cp; + int n; + int is_png = 0; char *tmpname; Imlib_Load_Error err; @@ -469,15 +472,52 @@ tmpname = feh_unique_filename("", "noname.png"); } - if (!opt.quiet) +//-------------------------------------------------------------------- + +// This code serves two purposes: + +// 1. As of mid-2007, "imlib2" supports "gif" input files, but it ap- +// parently lacks support for "gif" output files. Therefore, the old +// version of this routine fails when "gif" output files are genera- +// ted. As a workaround, the new version changes "gif" output files +// into "png" output files. + +// Note: It should be safe to modify the "tmpname" string here, as +// long as no attempt is made to write past the end of the associated +// storage space. + +// 2. If a "png" file is going to be written, this code sets "is_png" +// to a non-zero value. + + if ((n = strlen (tmpname)) > 4) + { + cp = &tmpname [n - 3]; + if (!strcasecmp (cp, "gif")) strcpy (cp, "png"); + if (!strcasecmp (cp, "png")) is_png = 1; + } + +//-------------------------------------------------------------------- + + if (!opt.quiet) printf("saving image to filename '%s'\n", tmpname); gib_imlib_save_image_with_error_return(win->im, tmpname, &err); if (err) weprintf("Can't save image %s:", tmpname); - free(tmpname); - return; +// If "optipng" is installed, this code optimizes "png" output files +// to a limited extent [the "-o1" switch used here selects speed over +// efficiency]. If "optipng" isn't installed, this code produces a +// non-fatal error message. + + if (is_png) + { + cp = estrjoin (" ", "optipng -o1", tmpname, NULL); + system (cp); + free (cp); + } + + free(tmpname); } gib_list *feh_list_jump(gib_list * root, gib_list * l, int direction, int num) --- feh-1.10.1.old/src/winwidget.c +++ feh-1.10.1/src/winwidget.c @@ -293,7 +293,18 @@ XSetCommand(disp, ret->win, cmdargv, cmdargc); winwidget_register(ret); - return; + + XEvent event; + XSelectInput (disp, ret->win, + StructureNotifyMask | SubstructureRedirectMask | + ResizeRedirectMask | KeyPressMask | KeyReleaseMask); + XRaiseWindow (disp, ret->win); + XMapWindow (disp, ret->win); + do { XNextEvent (disp, &event); } + while (event.type != MapNotify); + XGrabKeyboard (disp, ret->win, False, + GrabModeAsync, GrabModeAsync, CurrentTime); + XRaiseWindow (disp, ret->win); } void winwidget_update_title(winwidget ret) @@ -424,7 +435,7 @@ smaller = ((winwid->im_w < max_w) && (winwid->im_h < max_h)); - if (!smaller || opt.auto_zoom) { + if (opt.auto_zoom) { double ratio = 0.0; /* Image is larger than the screen (so wants shrinking), or it's