summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/filelist.c29
-rw-r--r--src/filelist.h3
-rw-r--r--src/help.raw4
-rw-r--r--src/imlib.c40
-rw-r--r--src/keyevents.c6
-rw-r--r--src/menu.c12
-rw-r--r--src/options.c6
-rw-r--r--src/options.h2
-rw-r--r--src/slideshow.c50
9 files changed, 144 insertions, 8 deletions
diff --git a/src/filelist.c b/src/filelist.c
index 542dbdf..3ea0928 100644
--- a/src/filelist.c
+++ b/src/filelist.c
@@ -185,6 +185,11 @@ void add_file_to_filelist_recursively(char *origpath, unsigned char level)
/* We'll download it later... */
free(path);
return;
+ } else if ((len == 1) && (path[0] == '-')) {
+ D(("Addig stdin (-) to filelist\n"));
+ filelist = gib_list_add_front(filelist, feh_file_new(path));
+ free(path);
+ return;
} else if (opt.filelistfile) {
char *newpath = feh_absolute_path(path);
@@ -354,6 +359,25 @@ int feh_cmp_name(void *file1, void *file2)
return(strcmp(FEH_FILE(file1)->name, FEH_FILE(file2)->name));
}
+/* Return -1 if file1 is _newer_ than file2 */
+int feh_cmp_mtime(void *file1, void *file2)
+{
+ struct stat s1, s2;
+
+ if (stat(FEH_FILE(file1)->filename, &s1)) {
+ feh_print_stat_error(FEH_FILE(file1)->filename);
+ return(-1);
+ }
+
+ if (stat(FEH_FILE(file2)->filename, &s2)) {
+ feh_print_stat_error(FEH_FILE(file2)->filename);
+ return(-1);
+ }
+
+ /* gib_list_sort is not stable, so explicitly return 0 as -1 */
+ return(s1.st_mtime >= s2.st_mtime ? -1 : 1);
+}
+
int feh_cmp_width(void *file1, void *file2)
{
return((FEH_FILE(file1)->info->width - FEH_FILE(file2)->info->width));
@@ -381,7 +405,7 @@ int feh_cmp_format(void *file1, void *file2)
void feh_prepare_filelist(void)
{
- if (opt.list || opt.customlist || (opt.sort > SORT_FILENAME)
+ if (opt.list || opt.customlist || (opt.sort > SORT_MTIME)
|| opt.preload || opt.min_width || opt.min_height
|| (opt.max_width != UINT_MAX) || (opt.max_height != UINT_MAX)) {
/* For these sort options, we have to preload images */
@@ -407,6 +431,9 @@ void feh_prepare_filelist(void)
case SORT_FILENAME:
filelist = gib_list_sort(filelist, feh_cmp_filename);
break;
+ case SORT_MTIME:
+ filelist = gib_list_sort(filelist, feh_cmp_mtime);
+ break;
case SORT_WIDTH:
filelist = gib_list_sort(filelist, feh_cmp_width);
break;
diff --git a/src/filelist.h b/src/filelist.h
index 00e36e8..7bfd518 100644
--- a/src/filelist.h
+++ b/src/filelist.h
@@ -56,7 +56,7 @@ struct __feh_file_info {
enum filelist_recurse { FILELIST_FIRST, FILELIST_CONTINUE, FILELIST_LAST };
-enum sort_type { SORT_NONE, SORT_NAME, SORT_FILENAME, SORT_WIDTH,
+enum sort_type { SORT_NONE, SORT_NAME, SORT_FILENAME, SORT_MTIME, SORT_WIDTH,
SORT_HEIGHT,
SORT_PIXELS,
SORT_SIZE, SORT_FORMAT
@@ -82,6 +82,7 @@ void feh_save_filelist();
int feh_cmp_name(void *file1, void *file2);
int feh_cmp_filename(void *file1, void *file2);
+int feh_cmp_mtime(void *file1, void *file2);
int feh_cmp_width(void *file1, void *file2);
int feh_cmp_height(void *file1, void *file2);
int feh_cmp_pixels(void *file1, void *file2);
diff --git a/src/help.raw b/src/help.raw
index 8e25b00..462e715 100644
--- a/src/help.raw
+++ b/src/help.raw
@@ -28,6 +28,7 @@ OPTIONS
mode or when window geometry is fixed. If combined
with --auto-zoom, zooming will be limited to the
the size.
+ --keep-zoom-vp Keep viewport zoom and settings while changing images
-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
@@ -45,7 +46,8 @@ OPTIONS
-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
+ name, filename, mtime, width, height, pixels, size,
+ or format
-n, --reverse Reverse sort order
-A, --action ACTION Specify action to perform when pressing <return>.
Executed by /bin/sh, may contain FORMAT SPECIFIERS
diff --git a/src/imlib.c b/src/imlib.c
index e9f92ad..bdf54ac 100644
--- a/src/imlib.c
+++ b/src/imlib.c
@@ -61,6 +61,7 @@ int num_xinerama_screens;
int childpid = 0;
+static char *feh_stdin_load_image();
static char *feh_http_load_image(char *url);
static char *feh_magick_load_image(char *filename);
@@ -209,7 +210,8 @@ void feh_imlib_print_load_error(char *file, winwidget w, Imlib_Load_Error err)
int feh_load_image(Imlib_Image * im, feh_file * file)
{
Imlib_Load_Error err;
- enum { SRC_IMLIB, SRC_HTTP, SRC_MAGICK } image_source = SRC_IMLIB;
+ enum { SRC_IMLIB, SRC_HTTP, SRC_MAGICK, SRC_STDIN } image_source =
+ SRC_IMLIB;
char *tmpname = NULL;
char *real_filename = NULL;
@@ -225,6 +227,10 @@ int feh_load_image(Imlib_Image * im, feh_file * file)
tmpname = feh_http_load_image(file->filename);
}
+ if ((strlen(file->filename) == 1) && (file->filename[0] == '-')) {
+ image_source = SRC_STDIN;
+ tmpname = feh_stdin_load_image();
+ }
else
*im = imlib_load_image_with_error_return(file->filename, &err);
@@ -269,6 +275,38 @@ int feh_load_image(Imlib_Image * im, feh_file * file)
return(1);
}
+static char *feh_stdin_load_image()
+{
+ char buf[1024];
+ size_t readsize;
+ char *sfn = estrjoin("_", "/tmp/feh_stdin", "XXXXXX", NULL);
+ int fd = mkstemp(sfn);
+ FILE *outfile;
+
+ if (fd == -1) {
+ free(sfn);
+ return NULL;
+ }
+
+ outfile = fdopen(fd, "w");
+
+ if (outfile == NULL) {
+ free(sfn);
+ return NULL;
+ }
+
+ while ((readsize = fread(buf, sizeof(char), sizeof(buf), stdin)) > 0) {
+ if (fwrite(buf, sizeof(char), readsize, outfile) < readsize) {
+ free(sfn);
+ return NULL;
+ }
+ }
+
+ fclose(outfile);
+
+ return sfn;
+}
+
static char *feh_magick_load_image(char *filename)
{
char argv_fd[12];
diff --git a/src/keyevents.c b/src/keyevents.c
index 470d624..9bda112 100644
--- a/src/keyevents.c
+++ b/src/keyevents.c
@@ -154,6 +154,7 @@ void init_keyevents(void) {
feh_set_kb(&keys.mirror, 0, XK_bar, 0, 0, 0, 0);
feh_set_kb(&keys.reload_minus, 0, XK_minus, 0, 0, 0, 0);
feh_set_kb(&keys.reload_plus, 0, XK_plus, 0, 0, 0, 0);
+ feh_set_kb(&keys.toggle_keep_vp, 0, XK_k, 0, 0, 0, 0);
home = getenv("HOME");
if (!home)
@@ -307,6 +308,8 @@ void init_keyevents(void) {
cur_kb = &keys.reload_minus;
else if (!strcmp(action, "reload_plus"))
cur_kb = &keys.reload_plus;
+ else if (!strcmp(action, "toggle_keep_vp"))
+ cur_kb = &keys.toggle_keep_vp;
else
weprintf("keys: Invalid action: %s", action);
@@ -761,5 +764,8 @@ void feh_event_handle_keypress(XEvent * ev)
else if (opt.verbose)
weprintf("Cannot set RELOAD lower than 1 second.");
}
+ else if (feh_is_kp(&keys.toggle_keep_vp, keysym, state)) {
+ opt.keep_zoom_vp = !opt.keep_zoom_vp;
+ }
return;
}
diff --git a/src/menu.c b/src/menu.c
index ee045ae..722ce02 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -56,7 +56,7 @@ enum {
CB_SORT_FILENAME, CB_SORT_IMAGENAME, CB_SORT_FILESIZE, CB_SORT_RANDOMIZE,
CB_SAVE_IMAGE, CB_SAVE_FILELIST, CB_FIT, CB_OPT_DRAW_FILENAME,
CB_OPT_DRAW_ACTIONS, CB_OPT_KEEP_HTTP, CB_OPT_FREEZE_WINDOW,
- CB_OPT_FULLSCREEN, CB_EDIT_ROTATE, CB_OPT_AUTO_ZOOM
+ CB_OPT_FULLSCREEN, CB_EDIT_ROTATE, CB_OPT_AUTO_ZOOM, CB_OPT_KEEP_ZOOM_VP
};
feh_menu *feh_menu_new(void)
@@ -1326,6 +1326,14 @@ void feh_menu_cb(feh_menu * m, feh_menu_item * i, int action, unsigned short dat
opt.zoom_mode = 0;
winwidget_rerender_all(1);
break;
+ case CB_OPT_KEEP_ZOOM_VP:
+ MENU_ITEM_TOGGLE(i);
+ if (MENU_ITEM_IS_ON(i))
+ opt.keep_zoom_vp = 1;
+ else
+ opt.keep_zoom_vp = 0;
+ winwidget_rerender_all(1);
+ break;
}
return;
}
@@ -1381,6 +1389,8 @@ static feh_menu *feh_menu_func_gen_options(feh_menu * m)
CB_OPT_FREEZE_WINDOW, 0, NULL, opt.geom_flags);
feh_menu_add_toggle_entry(mm, "Fullscreen", NULL,
CB_OPT_FULLSCREEN, 0, NULL, m->fehwin->full_screen);
+ feh_menu_add_toggle_entry(mm, "Keep viewport zoom & pos", NULL,
+ CB_OPT_KEEP_ZOOM_VP, 0, NULL, opt.keep_zoom_vp);
feh_menu_add_entry(mm, NULL, NULL, 0, 0, NULL);
diff --git a/src/options.c b/src/options.c
index 240b0d6..469115e 100644
--- a/src/options.c
+++ b/src/options.c
@@ -397,6 +397,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
{"info" , 1, 0, 234},
{"force-aliasing", 0, 0, 235},
{"no-fehbg" , 0, 0, 236},
+ {"keep-zoom-vp" , 0, 0, 237},
{0, 0, 0, 0}
};
@@ -500,6 +501,8 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
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"))
@@ -722,6 +725,9 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
case 236:
opt.no_fehbg = 1;
break;
+ case 237:
+ opt.keep_zoom_vp = 1;
+ break;
default:
break;
}
diff --git a/src/options.h b/src/options.h
index d30c396..f3f49eb 100644
--- a/src/options.h
+++ b/src/options.h
@@ -72,6 +72,7 @@ struct __fehoptions {
unsigned char text_bg;
unsigned char image_bg;
unsigned char no_fehbg;
+ unsigned char keep_zoom_vp;
char *output_file;
char *output_dir;
@@ -189,6 +190,7 @@ struct __fehkb {
struct __fehkey toggle_fullscreen;
struct __fehkey reload_minus;
struct __fehkey reload_plus;
+ struct __fehkey toggle_keep_vp;
};
struct __fehbutton {
diff --git a/src/slideshow.c b/src/slideshow.c
index d79c859..65aae3d 100644
--- a/src/slideshow.c
+++ b/src/slideshow.c
@@ -149,6 +149,16 @@ void feh_reload_image(winwidget w, int resize, int force_new)
Imlib_Image tmp;
int old_w, old_h;
+ unsigned char tmode =0;
+ int tim_x =0;
+ int tim_y =0;
+ double tzoom =0;
+
+ tmode = w->mode;
+ tim_x = w->im_x;
+ tim_y = w->im_y;
+ tzoom = w->zoom;
+
if (!w->file) {
im_weprintf(w, "couldn't reload, this image has no file associated with it.");
winwidget_render_image(w, 0, 0);
@@ -216,7 +226,16 @@ void feh_reload_image(winwidget w, int resize, int force_new)
w->im_w = gib_imlib_image_get_width(w->im);
w->im_h = gib_imlib_image_get_height(w->im);
}
- winwidget_render_image(w, resize, 0);
+ if (opt.keep_zoom_vp) {
+ /* put back in: */
+ w->mode = tmode;
+ w->im_x = tim_x;
+ w->im_y = tim_y;
+ w->zoom = tzoom;
+ winwidget_render_image(w, 0, 0);
+ } else {
+ winwidget_render_image(w, resize, 0);
+ }
winwidget_rename(w, title);
free(title);
@@ -236,6 +255,11 @@ void slideshow_change_image(winwidget winwid, int change, int render)
int our_filelist_len = filelist_len;
char *s;
+ unsigned char tmode =0;
+ int tim_x =0;
+ int tim_y =0;
+ double tzoom =0;
+
/* Without this, clicking a one-image slideshow reloads it. Not very *
intelligent behaviour :-) */
if (filelist_len < 2 && opt.cycle_once == 0)
@@ -308,6 +332,14 @@ void slideshow_change_image(winwidget winwid, int change, int render)
last = NULL;
}
+ if (opt.keep_zoom_vp) {
+ /* pre loadimage - record settings */
+ tmode = winwid->mode;
+ tim_x = winwid->im_x;
+ tim_y = winwid->im_y;
+ tzoom = winwid->zoom;
+ }
+
if ((winwidget_loadimage(winwid, FEH_FILE(current_file->data)))
!= 0) {
winwid->mode = MODE_NORMAL;
@@ -318,8 +350,20 @@ void slideshow_change_image(winwidget winwid, int change, int render)
winwidget_reset_image(winwid);
winwid->im_w = gib_imlib_image_get_width(winwid->im);
winwid->im_h = gib_imlib_image_get_height(winwid->im);
- if (render)
- winwidget_render_image(winwid, 1, 0);
+ if (opt.keep_zoom_vp) {
+ /* put back in: */
+ winwid->mode = tmode;
+ winwid->im_x = tim_x;
+ winwid->im_y = tim_y;
+ winwid->zoom = tzoom;
+ }
+ if (render) {
+ if (opt.keep_zoom_vp) {
+ winwidget_render_image(winwid, 0, 0);
+ } else {
+ winwidget_render_image(winwid, 1, 0);
+ }
+ }
s = slideshow_create_name(FEH_FILE(current_file->data), winwid);
winwidget_rename(winwid, s);