From 5cf2736a8a7f6b8df8f2793b095f219941a34338 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Fri, 25 Aug 2017 11:07:53 +0200 Subject: Disable stdin control in multiwindow mode As there's no "default" window, it doesn't make much sense here... Plus, it's buggy as hell in this mode --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index 57b7a7b..0f2844f 100644 --- a/src/main.c +++ b/src/main.c @@ -111,7 +111,7 @@ int feh_main_iteration(int block) fdsize = xfd + 1; pt = feh_get_time(); first = 0; - if (isatty(STDIN_FILENO)) { + if (isatty(STDIN_FILENO) && !opt.multiwindow) { control_via_stdin = 1; struct termios ctrl; if (tcgetattr(STDIN_FILENO, &old_term_settings) == -1) -- cgit v1.2.3 From b6782ccf1fa9e0f1778b79bdaf2367c8a84a1d6c Mon Sep 17 00:00:00 2001 From: orbea Date: Fri, 25 Aug 2017 10:23:25 -0700 Subject: Silence warnings --- src/imlib.c | 2 +- src/utils.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/imlib.c b/src/imlib.c index ecc44b5..cdc4fe7 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -1262,7 +1262,7 @@ void feh_draw_actions(winwidget w) int i = 0; int num_actions = 0; int cur_action = 0; - char index[2]; + char index[3]; char *line; /* Count number of defined actions. This method sucks a bit since it needs diff --git a/src/utils.c b/src/utils.c index 4c06a48..dfae909 100644 --- a/src/utils.c +++ b/src/utils.c @@ -157,7 +157,7 @@ char *feh_unique_filename(char *path, char *basename) { char *tmpname; char num[10]; - char cppid[10]; + char cppid[12]; static long int i = 1; struct stat st; pid_t ppid; -- cgit v1.2.3 From 7391cd1fe2d92b705f0089221eaa12bc3fdf7058 Mon Sep 17 00:00:00 2001 From: orbea Date: Fri, 25 Aug 2017 11:04:06 -0700 Subject: (src/Makefile) Manually set the target *.c files This allows finer control of which files are compiled and additionally will silence some -Wpedantic warnings when "empty" files are compiled. --- src/Makefile | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile b/src/Makefile index 0e2c543..2f6185a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,6 +1,40 @@ include ../config.mk -TARGETS = ${shell echo *.c} +TARGETS = \ + collage.c \ + events.c \ + feh_png.c \ + filelist.c \ + getopt.c \ + getopt1.c \ + gib_hash.c \ + gib_imlib.c \ + gib_list.c \ + gib_style.c \ + imlib.c \ + index.c \ + keyevents.c \ + list.c \ + main.c \ + md5.c \ + menu.c \ + multiwindow.c \ + options.c \ + signals.c \ + slideshow.c \ + thumbnail.c \ + timers.c \ + utils.c \ + wallpaper.c \ + winwidget.c + +ifeq (${exif},1) + TARGETS += \ + exif.c \ + exif_canon.c \ + exif_nikon.c +endif + OBJECTS = ${TARGETS:.c=.o} I_SRCS = ${shell echo *.raw} -- cgit v1.2.3 From a0e2ed52478480513dc1f6963f3114c7841a0d87 Mon Sep 17 00:00:00 2001 From: orbea Date: Fri, 25 Aug 2017 14:03:39 -0700 Subject: Silence -Wimplicit-fallthrough= warning --- src/options.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/options.c b/src/options.c index 56323a8..4f87685 100644 --- a/src/options.c +++ b/src/options.c @@ -768,6 +768,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) break; case 240: opt.insecure_ssl = 1; + break; case 241: opt.recursive = 0; default: -- cgit v1.2.3 From 9e146eb61690404a33c80645fbb46b696d48d484 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sun, 27 Aug 2017 12:39:03 +0200 Subject: Do not accept control from stdin when running in the background --- src/main.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index 0f2844f..b3f121c 100644 --- a/src/main.c +++ b/src/main.c @@ -111,7 +111,17 @@ int feh_main_iteration(int block) fdsize = xfd + 1; pt = feh_get_time(); first = 0; - if (isatty(STDIN_FILENO) && !opt.multiwindow) { + /* + * Only accept commands from stdin if + * - stdin is a terminal (otherwise it's probably used as an image / filelist) + * - we aren't running in multiwindow mode (cause it's not clear which + * window commands should be applied to in that case) + * - we're in the same process group as stdin, AKA we're not running + * in the background. Background processes are stopped with SIGTTOU + * if they try to write to stdout or change terminal attributes. They + * also don't get input from stdin anyway. + */ + if (isatty(STDIN_FILENO) && !opt.multiwindow && getpgrp() == (tcgetpgrp(STDIN_FILENO))) { control_via_stdin = 1; struct termios ctrl; if (tcgetattr(STDIN_FILENO, &old_term_settings) == -1) -- cgit v1.2.3 From cbf6925bba7c10cc662e375e1ab6cd47c3b1d481 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Tue, 29 Aug 2017 12:35:22 +0200 Subject: Handle detaching the controlling tty from a feh process --- src/feh.h | 2 ++ src/keyevents.c | 3 ++- src/main.c | 2 +- src/signals.c | 10 ++++++++-- 4 files changed, 13 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/feh.h b/src/feh.h index 4572652..fb9fefe 100644 --- a/src/feh.h +++ b/src/feh.h @@ -201,4 +201,6 @@ extern char *mode; /* label for the current mode */ /* to terminate long-running children with SIGALRM */ extern int childpid; +extern int control_via_stdin; + #endif diff --git a/src/keyevents.c b/src/keyevents.c index b5c1949..2e49676 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -271,7 +271,8 @@ void feh_event_handle_stdin() char stdin_buf[2]; KeySym keysym = NoSymbol; if (read(STDIN_FILENO, &stdin_buf, 1) == -1) { - weprintf("reading a command from stdin failed"); + if (control_via_stdin) + weprintf("reading a command from stdin failed"); return; } stdin_buf[1] = '\0'; diff --git a/src/main.c b/src/main.c index b3f121c..cb2964f 100644 --- a/src/main.c +++ b/src/main.c @@ -234,7 +234,7 @@ void feh_clean_exit(void) if(disp) XCloseDisplay(disp); - if (control_via_stdin) + if (control_via_stdin && isatty(STDIN_FILENO)) if (tcsetattr(STDIN_FILENO, TCSANOW, &old_term_settings) == -1) eprintf("tcsetattr failed"); diff --git a/src/signals.c b/src/signals.c index 0b18aac..8a3a8f7 100644 --- a/src/signals.c +++ b/src/signals.c @@ -40,7 +40,8 @@ void setup_signal_handlers() (sigaddset(&feh_ss, SIGALRM) == -1) || (sigaddset(&feh_ss, SIGTERM) == -1) || (sigaddset(&feh_ss, SIGQUIT) == -1) || - (sigaddset(&feh_ss, SIGINT) == -1)) + (sigaddset(&feh_ss, SIGINT) == -1) || + (sigaddset(&feh_ss, SIGTTIN) == -1)) { weprintf("Failed to set up signal masks"); return; @@ -56,7 +57,8 @@ void setup_signal_handlers() (sigaction(SIGALRM, &feh_sh, NULL) == -1) || (sigaction(SIGTERM, &feh_sh, NULL) == -1) || (sigaction(SIGQUIT, &feh_sh, NULL) == -1) || - (sigaction(SIGINT, &feh_sh, NULL) == -1)) + (sigaction(SIGINT, &feh_sh, NULL) == -1) || + (sigaction(SIGTTIN, &feh_sh, NULL) == -1)) { weprintf("Failed to set up signal handler"); return; @@ -75,6 +77,10 @@ void feh_handle_signal(int signo) if (childpid) killpg(childpid, SIGINT); return; + case SIGTTIN: + // we were probably backgrounded while we were running + control_via_stdin = 0; + return; case SIGINT: case SIGTERM: case SIGQUIT: -- cgit v1.2.3 From 2384a2005a60c5b992d3488cdf1075b741704744 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Thu, 31 Aug 2017 10:58:07 +0200 Subject: Add support for caption editing to stdin key input --- src/keyevents.c | 105 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 54 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/keyevents.c b/src/keyevents.c index 2e49676..44ed1e9 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -281,6 +281,8 @@ void feh_event_handle_stdin() keysym = XK_space; else if (stdin_buf[0] == '\n') keysym = XK_Return; + else if ((stdin_buf[0] == '\b') || (stdin_buf[0] == 127)) + keysym = XK_BackSpace; else keysym = XStringToKeysym(stdin_buf); @@ -333,57 +335,6 @@ void feh_event_handle_keypress(XEvent * ev) if (winwid == NULL) return; - if (winwid->caption_entry) { - switch (keysym) { - case XK_Return: - if (state & ControlMask) { - /* insert actual newline */ - ESTRAPPEND(FEH_FILE(winwid->file->data)->caption, "\n"); - winwidget_render_image_cached(winwid); - } else { - /* finish caption entry, write to captions file */ - FILE *fp; - char *caption_filename; - caption_filename = - build_caption_filename(FEH_FILE(winwid->file->data), 1); - winwid->caption_entry = 0; - winwidget_render_image_cached(winwid); - XFreePixmap(disp, winwid->bg_pmap_cache); - winwid->bg_pmap_cache = 0; - fp = fopen(caption_filename, "w"); - if (!fp) { - eprintf("couldn't write to captions file %s:", caption_filename); - return; - } - fprintf(fp, "%s", FEH_FILE(winwid->file->data)->caption); - free(caption_filename); - fclose(fp); - } - break; - case XK_Escape: - /* cancel, revert caption */ - winwid->caption_entry = 0; - free(FEH_FILE(winwid->file->data)->caption); - FEH_FILE(winwid->file->data)->caption = NULL; - winwidget_render_image_cached(winwid); - XFreePixmap(disp, winwid->bg_pmap_cache); - winwid->bg_pmap_cache = 0; - break; - case XK_BackSpace: - /* backspace */ - ESTRTRUNC(FEH_FILE(winwid->file->data)->caption, 1); - winwidget_render_image_cached(winwid); - break; - default: - if (isascii(keysym)) { - /* append to caption */ - ESTRAPPEND_CHAR(FEH_FILE(winwid->file->data)->caption, keysym); - winwidget_render_image_cached(winwid); - } - break; - } - return; - } feh_event_handle_generic(winwid, state, keysym, 0); } @@ -526,6 +477,58 @@ fehkey *feh_str_to_kb(char *action) void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysym, unsigned int button) { int curr_screen = 0; + if (winwid->caption_entry && (keysym != NoSymbol)) { + switch (keysym) { + case XK_Return: + if (state & ControlMask) { + /* insert actual newline */ + ESTRAPPEND(FEH_FILE(winwid->file->data)->caption, "\n"); + winwidget_render_image_cached(winwid); + } else { + /* finish caption entry, write to captions file */ + FILE *fp; + char *caption_filename; + caption_filename = + build_caption_filename(FEH_FILE(winwid->file->data), 1); + winwid->caption_entry = 0; + winwidget_render_image_cached(winwid); + XFreePixmap(disp, winwid->bg_pmap_cache); + winwid->bg_pmap_cache = 0; + fp = fopen(caption_filename, "w"); + if (!fp) { + eprintf("couldn't write to captions file %s:", caption_filename); + return; + } + fprintf(fp, "%s", FEH_FILE(winwid->file->data)->caption); + free(caption_filename); + fclose(fp); + } + break; + case XK_Escape: + /* cancel, revert caption */ + winwid->caption_entry = 0; + free(FEH_FILE(winwid->file->data)->caption); + FEH_FILE(winwid->file->data)->caption = NULL; + winwidget_render_image_cached(winwid); + XFreePixmap(disp, winwid->bg_pmap_cache); + winwid->bg_pmap_cache = 0; + break; + case XK_BackSpace: + /* backspace */ + ESTRTRUNC(FEH_FILE(winwid->file->data)->caption, 1); + winwidget_render_image_cached(winwid); + break; + default: + if (isascii(keysym)) { + /* append to caption */ + ESTRAPPEND_CHAR(FEH_FILE(winwid->file->data)->caption, keysym); + winwidget_render_image_cached(winwid); + } + break; + } + return; + } + if (feh_is_kp(&keys.next_img, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_NEXT, 1); -- cgit v1.2.3 From 8ad7d16318975a46aaada5c2b4ecf22c089b88f5 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sat, 2 Sep 2017 09:23:55 +0200 Subject: Respect -N / --no-menus option (broken in 2.17) --- src/keyevents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/keyevents.c b/src/keyevents.c index 44ed1e9..7b0923a 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -768,7 +768,7 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy else if (feh_is_kp(&keys.size_to_image, state, keysym, button)) { winwidget_size_to_image(winwid); } - else if (feh_is_kp(&keys.toggle_menu, state, keysym, button)) { + else if (!opt.no_menus && feh_is_kp(&keys.toggle_menu, state, keysym, button)) { winwidget_show_menu(winwid); } else if (feh_is_kp(&keys.close, state, keysym, button)) { -- cgit v1.2.3 From d77e4f0a32866f164556e9de8faec3923c7b314e Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Tue, 5 Sep 2017 00:03:20 +0200 Subject: Remove image from filelist if it was removed by an action (closes #322) --- src/keyevents.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/keyevents.c b/src/keyevents.c index 7b0923a..a6833a6 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -234,12 +234,15 @@ static short feh_is_kp(fehkey *key, unsigned int state, unsigned int sym, unsign void feh_event_invoke_action(winwidget winwid, unsigned char action) { + struct stat st; if (opt.actions[action]) { if (opt.slideshow) { feh_action_run(FEH_FILE(winwid->file->data), opt.actions[action], winwid); if (opt.hold_actions[action]) feh_reload_image(winwid, 1, 1); + else if (stat(FEH_FILE(winwid->file->data)->filename, &st) == -1) + feh_filelist_image_remove(winwid, 0); else slideshow_change_image(winwid, SLIDE_NEXT, 1); -- cgit v1.2.3 From 72cafcccdeabe56809d26e0afac5de6d3c331150 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Tue, 5 Sep 2017 18:14:56 +0200 Subject: Work around ImageMagick bug when converting to file descriptors (#323) --- src/imlib.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/imlib.c b/src/imlib.c index cdc4fe7..71b0a81 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -283,7 +283,7 @@ int feh_load_image(Imlib_Image * im, feh_file * file) static char *feh_magick_load_image(char *filename) { - char argv_fd[12]; + char *argv_fn; char *basename; char *tmpname; char *sfn; @@ -310,10 +310,17 @@ static char *feh_magick_load_image(char *filename) fd = mkstemp(sfn); - if (fd == -1) + if (fd == -1) { + free(sfn); return NULL; + } - snprintf(argv_fd, sizeof(argv_fd), "png:fd:%d", fd); + /* + * We could use png:fd:(whatever mkstemp returned) as target filename + * for convert, but this seems to be broken in some ImageMagick versions. + * So we resort to png:(sfn) instead. + */ + argv_fn = estrjoin(":", "png", sfn, NULL); if ((childpid = fork()) < 0) { weprintf("%s: Can't load with imagemagick. Fork failed:", filename); @@ -336,7 +343,7 @@ static char *feh_magick_load_image(char *filename) */ setpgid(0, 0); - execlp("convert", "convert", filename, argv_fd, NULL); + execlp("convert", "convert", filename, argv_fn, NULL); _exit(1); } else { @@ -369,6 +376,7 @@ static char *feh_magick_load_image(char *filename) childpid = 0; } + free(argv_fn); return sfn; } -- cgit v1.2.3 From 284207b12dbfd13c25416cba69a151f54dabb6dc Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 13 Sep 2017 18:34:44 +0200 Subject: Only restore terminal settings if stdin still belongs to us (closes #324) --- src/main.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index cb2964f..bb4dec4 100644 --- a/src/main.c +++ b/src/main.c @@ -234,7 +234,15 @@ void feh_clean_exit(void) if(disp) XCloseDisplay(disp); - if (control_via_stdin && isatty(STDIN_FILENO)) + /* + * Only restore the old terminal settings if + * - we changed them in the first place + * - stdin still is a terminal (it might have been closed) + * - stdin still belongs to us (we might have been detached from the + * controlling terminal, in that case we probably shouldn't be messing + * around with it) + */ + if (control_via_stdin && isatty(STDIN_FILENO) && getpgrp() == (tcgetpgrp(STDIN_FILENO))) if (tcsetattr(STDIN_FILENO, TCSANOW, &old_term_settings) == -1) eprintf("tcsetattr failed"); -- cgit v1.2.3 From 820838242134f6bc2078610a6498a62722bca239 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 13 Sep 2017 18:53:45 +0200 Subject: Improve handling of lost terminals When feh loses its controlling terminal at runtime, e.g. due to backgrounding / disowning, it will no longer issue a warning on each terminal keystroke. --- src/feh.h | 4 +++- src/keyevents.c | 35 +++++++++++++++++++++++++++++++++-- src/main.c | 20 ++------------------ 3 files changed, 38 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/feh.h b/src/feh.h index fb9fefe..a4a0a7b 100644 --- a/src/feh.h +++ b/src/feh.h @@ -141,6 +141,8 @@ char *slideshow_create_name(feh_file * file, winwidget winwid); char *thumbnail_create_name(feh_file * file, winwidget winwid); void init_keyevents(void); void init_buttonbindings(void); +void setup_stdin(void); +void restore_stdin(void); void feh_event_handle_keypress(XEvent * ev); void feh_event_handle_stdin(); void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysym, unsigned int button); @@ -201,6 +203,6 @@ extern char *mode; /* label for the current mode */ /* to terminate long-running children with SIGALRM */ extern int childpid; -extern int control_via_stdin; +extern unsigned char control_via_stdin; #endif diff --git a/src/keyevents.c b/src/keyevents.c index a6833a6..14f1a14 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -29,8 +29,36 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "filelist.h" #include "winwidget.h" #include "options.h" +#include fehkb keys; +struct termios old_term_settings; +unsigned char control_via_stdin = 0; + +void setup_stdin() { + struct termios ctrl; + + control_via_stdin = 1; + + if (tcgetattr(STDIN_FILENO, &old_term_settings) == -1) + eprintf("tcgetattr failed"); + if (tcgetattr(STDIN_FILENO, &ctrl) == -1) + eprintf("tcgetattr failed"); + + ctrl.c_iflag &= ~(PARMRK | ISTRIP + | INLCR | IGNCR | IXON); + ctrl.c_lflag &= ~(ECHO | ICANON | IEXTEN); + ctrl.c_cflag &= ~(CSIZE | PARENB); + ctrl.c_cflag |= CS8; + + if (tcsetattr(STDIN_FILENO, TCSANOW, &ctrl) == -1) + eprintf("tcsetattr failed"); +} + +void restore_stdin() { + if (tcsetattr(STDIN_FILENO, TCSANOW, &old_term_settings) == -1) + eprintf("tcsetattr failed"); +} static void feh_set_kb(fehkey *key, unsigned int s0, unsigned int y0, unsigned int s1, unsigned int y1, unsigned int s2, unsigned int y2) { @@ -274,8 +302,11 @@ void feh_event_handle_stdin() char stdin_buf[2]; KeySym keysym = NoSymbol; if (read(STDIN_FILENO, &stdin_buf, 1) == -1) { - if (control_via_stdin) - weprintf("reading a command from stdin failed"); + control_via_stdin = 0; + if (isatty(STDIN_FILENO) && getpgrp() == (tcgetpgrp(STDIN_FILENO))) { + weprintf("reading a command from stdin failed - disabling control via stdin"); + restore_stdin(); + } return; } stdin_buf[1] = '\0'; diff --git a/src/main.c b/src/main.c index bb4dec4..605c113 100644 --- a/src/main.c +++ b/src/main.c @@ -38,9 +38,6 @@ char **cmdargv = NULL; int cmdargc = 0; char *mode = NULL; -struct termios old_term_settings; -int control_via_stdin = 0; - int main(int argc, char **argv) { atexit(feh_clean_exit); @@ -122,19 +119,7 @@ int feh_main_iteration(int block) * also don't get input from stdin anyway. */ if (isatty(STDIN_FILENO) && !opt.multiwindow && getpgrp() == (tcgetpgrp(STDIN_FILENO))) { - control_via_stdin = 1; - struct termios ctrl; - if (tcgetattr(STDIN_FILENO, &old_term_settings) == -1) - eprintf("tcgetattr failed"); - if (tcgetattr(STDIN_FILENO, &ctrl) == -1) - eprintf("tcgetattr failed"); - ctrl.c_iflag &= ~(PARMRK | ISTRIP - | INLCR | IGNCR | IXON); - ctrl.c_lflag &= ~(ECHO | ICANON | IEXTEN); - ctrl.c_cflag &= ~(CSIZE | PARENB); - ctrl.c_cflag |= CS8; - if (tcsetattr(STDIN_FILENO, TCSANOW, &ctrl) == -1) - eprintf("tcsetattr failed"); + setup_stdin(); } } @@ -243,8 +228,7 @@ void feh_clean_exit(void) * around with it) */ if (control_via_stdin && isatty(STDIN_FILENO) && getpgrp() == (tcgetpgrp(STDIN_FILENO))) - if (tcsetattr(STDIN_FILENO, TCSANOW, &old_term_settings) == -1) - eprintf("tcsetattr failed"); + restore_stdin(); if (opt.filelistfile) feh_write_filelist(filelist, opt.filelistfile); -- cgit v1.2.3 From e91a10ecb2e1f7c237e77e47936932ce14fbec32 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sat, 16 Sep 2017 01:32:57 +0200 Subject: Replace legacy signal(...) call with sigaction(...) --- src/wallpaper.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/wallpaper.c b/src/wallpaper.c index 2f7810f..f40c613 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -779,10 +779,11 @@ void enl_ipc_send(char *str) return; } -static sighandler_t *enl_ipc_timeout(int sig) +void enl_ipc_timeout(int sig) { - timeout = 1; - return((sighandler_t *) sig); + if (sig == SIGALRM) + timeout = 1; + return; } char *enl_wait_for_reply(void) @@ -842,7 +843,8 @@ char *enl_ipc_get(const char *msg_data) char *enl_send_and_wait(char *msg) { char *reply = IPC_TIMEOUT; - sighandler_t old_alrm; + struct sigaction e17_sh, feh_sh; + sigset_t e17_ss; /* * Shortcut this func and return IPC_FAKE @@ -861,7 +863,19 @@ char *enl_send_and_wait(char *msg) sleep(1); } } - old_alrm = (sighandler_t) signal(SIGALRM, (sighandler_t) enl_ipc_timeout); + + if ((sigemptyset(&e17_ss) == -1) || sigaddset(&e17_ss, SIGALRM) == -1) { + weprintf("Failed to set up temporary E17 signal masks"); + return reply; + } + e17_sh.sa_handler = enl_ipc_timeout; + e17_sh.sa_mask = e17_ss; + e17_sh.sa_flags = 0; + if (sigaction(SIGALRM, &e17_sh, &feh_sh) == -1) { + weprintf("Failed to set up temporary E17 signal handler"); + return reply; + } + for (; reply == IPC_TIMEOUT;) { timeout = 0; enl_ipc_send(msg); @@ -873,6 +887,8 @@ char *enl_send_and_wait(char *msg) ipc_win = None; } } - signal(SIGALRM, old_alrm); + if (sigaction(SIGALRM, &feh_sh, NULL) == -1) { + weprintf("Failed to restore signal handler"); + } return(reply); } -- cgit v1.2.3 From a6b5acb94f1d851c738f23a86020783d77173b4d Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sat, 16 Sep 2017 11:15:27 +0200 Subject: Initialize png comment hash after setjmp() to avoid clobbering it --- src/feh_png.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/feh_png.c b/src/feh_png.c index ff73f56..d27df01 100644 --- a/src/feh_png.c +++ b/src/feh_png.c @@ -35,8 +35,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. gib_hash *feh_png_read_comments(char *file) { - gib_hash *hash = NULL; - FILE *fp; int i, sig_bytes, comments = 0; @@ -45,31 +43,31 @@ gib_hash *feh_png_read_comments(char *file) png_textp text_ptr; if (!(fp = fopen(file, "rb"))) - return hash; + return NULL; if (!(sig_bytes = feh_png_file_is_png(fp))) { fclose(fp); - return hash; + return NULL; } /* initialize data structures */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { fclose(fp); - return hash; + return NULL; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); fclose(fp); - return hash; + return NULL; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(fp); - return hash; + return NULL; } /* initialize reading */ @@ -78,6 +76,8 @@ gib_hash *feh_png_read_comments(char *file) png_read_info(png_ptr, info_ptr); + gib_hash *hash = NULL; + #ifdef PNG_TEXT_SUPPORTED png_get_text(png_ptr, info_ptr, &text_ptr, &comments); if (comments > 0) { -- cgit v1.2.3 From 7eb9d73e908d3c10c06521bb211dc571cb3a8e35 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sat, 16 Sep 2017 20:36:52 +0200 Subject: Add toggle_fixed_geometry ("g") keybinding to enable/disable window auto-resize Closes #326 --- man/feh.pre | 4 ++++ src/keyevents.c | 12 ++++++++++++ src/options.h | 1 + 3 files changed, 17 insertions(+) (limited to 'src') diff --git a/man/feh.pre b/man/feh.pre index fb5e28f..ac9a81a 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -1258,6 +1258,10 @@ Toggle EXIF tag display Save the current filelist as .Qq feh_PID_ID_filelist . +.It g Bq toggle_fixed_geometry +. +Enable/Disable automatic window resize when changing images. +. .It h Bq toggle_pause . Pause/Continue the slideshow. When it is paused, it will not automatically diff --git a/src/keyevents.c b/src/keyevents.c index 14f1a14..d478a5a 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -196,6 +196,7 @@ void init_keyevents(void) { 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); + feh_set_kb(&keys.toggle_fixed_geometry, 0, XK_g, 0, 0, 0, 0); home = getenv("HOME"); confhome = getenv("XDG_CONFIG_HOME"); @@ -504,6 +505,8 @@ fehkey *feh_str_to_kb(char *action) return &keys.reload_plus; else if (!strcmp(action, "toggle_keep_vp")) return &keys.toggle_keep_vp; + else if (!strcmp(action, "toggle_fixed_geometry")) + return &keys.toggle_fixed_geometry; return NULL; } @@ -871,5 +874,14 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy else if (feh_is_kp(&keys.toggle_keep_vp, state, keysym, button)) { opt.keep_zoom_vp = !opt.keep_zoom_vp; } + else if (feh_is_kp(&keys.toggle_fixed_geometry, state, keysym, button)) { + if (opt.geom_flags & ((WidthValue | HeightValue))) { + opt.geom_flags &= ~(WidthValue | HeightValue); + } else { + opt.geom_flags |= (WidthValue | HeightValue); + opt.geom_w = winwid->w; + opt.geom_h = winwid->h; + } + } return; } diff --git a/src/options.h b/src/options.h index 5a5ce84..ef7f471 100644 --- a/src/options.h +++ b/src/options.h @@ -208,6 +208,7 @@ struct __fehkb { struct __fehkey reload; struct __fehkey blur; struct __fehkey rotate; + struct __fehkey toggle_fixed_geometry; }; void init_parse_options(int argc, char **argv); -- cgit v1.2.3 From 1ed8c69012eb238082dc4bb6befa10fc7b9426fa Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sun, 24 Sep 2017 19:15:25 +0200 Subject: Replace keybinding struct with an array of named bindings --- src/events.c | 96 ++++++------- src/keyevents.c | 433 +++++++++++++++++++++----------------------------------- src/options.h | 143 +++++++++---------- 3 files changed, 272 insertions(+), 400 deletions(-) (limited to 'src') diff --git a/src/events.c b/src/events.c index b20fd4f..947e69f 100644 --- a/src/events.c +++ b/src/events.c @@ -35,7 +35,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define FEH_JITTER_OFFSET 2 #define FEH_JITTER_TIME 1 -extern fehkb keys; +extern struct __fehkey keys[EVENT_LIST_END]; +fehkey *feh_str_to_kb(char *action); feh_event_handler *ev_handler[LASTEvent]; @@ -45,10 +46,10 @@ static void feh_event_handle_LeaveNotify(XEvent * ev); static void feh_event_handle_MotionNotify(XEvent * ev); static void feh_event_handle_ClientMessage(XEvent * ev); -static void feh_set_bb(fehkey *bb, int modifier, char button) +static void feh_set_bb(unsigned int bb_index, int modifier, char button) { - bb->state = modifier; - bb->button = button; + keys[bb_index].state = modifier; + keys[bb_index].button = button; } static void feh_set_parse_bb_partial(fehkey *button, char *binding) @@ -101,13 +102,13 @@ void init_buttonbindings(void) FILE *conf = NULL; int read = 0; - feh_set_bb(&keys.pan, 0, 1); - feh_set_bb(&keys.zoom, 0, 2); - feh_set_bb(&keys.toggle_menu, 0, 3); - feh_set_bb(&keys.prev_img, 0, 4); - feh_set_bb(&keys.next_img, 0, 5); - feh_set_bb(&keys.blur, 4, 1); - feh_set_bb(&keys.rotate, 4, 2); + feh_set_bb(EVENT_pan, 0, 1); + feh_set_bb(EVENT_zoom, 0, 2); + feh_set_bb(EVENT_toggle_menu, 0, 3); + feh_set_bb(EVENT_prev_img, 0, 4); + feh_set_bb(EVENT_next_img, 0, 5); + feh_set_bb(EVENT_blur, 4, 1); + feh_set_bb(EVENT_rotate, 4, 2); home = getenv("HOME"); confhome = getenv("XDG_CONFIG_HOME"); @@ -136,34 +137,17 @@ void init_buttonbindings(void) if ((read == EOF) || (read == 0) || (line[0] == '#')) continue; - /* - * Note: This isn't really good code. But it works, and since it only - * runs once for each button config line the runtime penalty compared to - * e.g. a hash table is negligible in this case. - */ - if (!strcmp(action, "reload")) - cur_bb = &keys.reload; - else if (!strcmp(action, "pan")) - cur_bb = &keys.pan; - else if (!strcmp(action, "zoom")) - cur_bb = &keys.zoom; - else if (!strcmp(action, "menu") || !strcmp(action, "toggle_menu")) - cur_bb = &keys.toggle_menu; - else if (!strcmp(action, "prev") || !strcmp(action, "prev_img")) - cur_bb = &keys.prev_img; - else if (!strcmp(action, "next") || !strcmp(action, "next_img")) - cur_bb = &keys.next_img; - else if (!strcmp(action, "blur")) - cur_bb = &keys.blur; - else if (!strcmp(action, "rotate")) - cur_bb = &keys.rotate; - else if (!strcmp(action, "zoom_in")) - cur_bb = &keys.zoom_in; - else if (!strcmp(action, "zoom_out")) - cur_bb = &keys.zoom_out; - else - cur_bb = feh_str_to_kb(action); - + cur_bb = feh_str_to_kb(action); + if (cur_bb == NULL) { + if (!strcmp(action, "reload")) + cur_bb = &keys[EVENT_reload_image]; + else if (!strcmp(action, "menu")) + cur_bb = &keys[EVENT_toggle_menu]; + else if (!strcmp(action, "prev")) + cur_bb = &keys[EVENT_prev_img]; + else if (!strcmp(action, "next")) + cur_bb = &keys[EVENT_next_img]; + } if (cur_bb) feh_set_parse_bb_partial(cur_bb, button); else @@ -172,9 +156,9 @@ void init_buttonbindings(void) fclose(conf); } -static short feh_is_bb(fehkey *bb, unsigned int button, unsigned int mod) +static short feh_is_bb(unsigned int key_index, unsigned int button, unsigned int mod) { - if ((bb->state == mod) && (bb->button == button)) + if ((keys[key_index].state == mod) && (keys[key_index].button == button)) return 1; return 0; } @@ -217,23 +201,23 @@ static void feh_event_handle_ButtonPress(XEvent * ev) state = ev->xbutton.state & (ControlMask | ShiftMask | Mod1Mask | Mod4Mask); button = ev->xbutton.button; - if (!opt.no_menus && feh_is_bb(&keys.toggle_menu, button, state)) { + if (!opt.no_menus && feh_is_bb(EVENT_toggle_menu, button, state)) { D(("Menu Button Press event\n")); winwidget_show_menu(winwid); - } else if (feh_is_bb(&keys.rotate, button, state) + } else if (feh_is_bb(EVENT_rotate, button, state) && (winwid->type != WIN_TYPE_THUMBNAIL)) { opt.mode = MODE_ROTATE; winwid->mode = MODE_ROTATE; D(("rotate starting at %d, %d\n", ev->xbutton.x, ev->xbutton.y)); - } else if (feh_is_bb(&keys.blur, button, state) + } else if (feh_is_bb(EVENT_blur, button, state) && (winwid->type != WIN_TYPE_THUMBNAIL)) { opt.mode = MODE_BLUR; winwid->mode = MODE_BLUR; D(("blur starting at %d, %d\n", ev->xbutton.x, ev->xbutton.y)); - } else if (feh_is_bb(&keys.pan, button, state)) { + } else if (feh_is_bb(EVENT_pan, button, state)) { D(("Next button, but could be pan mode\n")); opt.mode = MODE_NEXT; winwid->mode = MODE_NEXT; @@ -242,7 +226,7 @@ static void feh_event_handle_ButtonPress(XEvent * ev) winwid->click_offset_y = ev->xbutton.y - winwid->im_y; winwid->click_start_time = time(NULL); - } else if (feh_is_bb(&keys.zoom, button, state)) { + } else if (feh_is_bb(EVENT_zoom, button, state)) { D(("Zoom Button Press event\n")); opt.mode = MODE_ZOOM; winwid->mode = MODE_ZOOM; @@ -257,7 +241,7 @@ static void feh_event_handle_ButtonPress(XEvent * ev) winwid->im_click_offset_y = (winwid->click_offset_y - winwid->im_y) / winwid->old_zoom; - } else if (feh_is_bb(&keys.zoom_in, button, state)) { + } else if (feh_is_bb(EVENT_zoom_in, button, state)) { D(("Zoom_In Button Press event\n")); D(("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y)); winwid->click_offset_x = ev->xbutton.x; @@ -285,7 +269,7 @@ static void feh_event_handle_ButtonPress(XEvent * ev) winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); - } else if (feh_is_bb(&keys.zoom_out, button, state)) { + } else if (feh_is_bb(EVENT_zoom_out, button, state)) { D(("Zoom_Out Button Press event\n")); D(("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y)); winwid->click_offset_x = ev->xbutton.x; @@ -313,16 +297,16 @@ static void feh_event_handle_ButtonPress(XEvent * ev) winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); - } else if (feh_is_bb(&keys.reload, button, state)) { + } else if (feh_is_bb(EVENT_reload_image, button, state)) { D(("Reload Button Press event\n")); feh_reload_image(winwid, 0, 1); - } else if (feh_is_bb(&keys.prev_img, button, state)) { + } else if (feh_is_bb(EVENT_prev_img, button, state)) { D(("Prev Button Press event\n")); if (winwid->type == WIN_TYPE_SLIDESHOW) slideshow_change_image(winwid, SLIDE_PREV, 1); - } else if (feh_is_bb(&keys.next_img, button, state)) { + } else if (feh_is_bb(EVENT_next_img, button, state)) { D(("Next Button Press event\n")); if (winwid->type == WIN_TYPE_SLIDESHOW) slideshow_change_image(winwid, SLIDE_NEXT, 1); @@ -363,7 +347,7 @@ static void feh_event_handle_ButtonRelease(XEvent * ev) return; } - if (feh_is_bb(&keys.pan, button, state)) { + if (feh_is_bb(EVENT_pan, button, state)) { if (opt.mode == MODE_PAN) { D(("Disabling pan mode\n")); opt.mode = MODE_NORMAL; @@ -401,13 +385,13 @@ static void feh_event_handle_ButtonRelease(XEvent * ev) winwid->mode = MODE_NORMAL; } - } else if (feh_is_bb(&keys.rotate, button, state) - || feh_is_bb(&keys.zoom, button, state)) { + } else if (feh_is_bb(EVENT_rotate, button, state) + || feh_is_bb(EVENT_zoom, button, state)) { D(("Disabling mode\n")); opt.mode = MODE_NORMAL; winwid->mode = MODE_NORMAL; - if ((feh_is_bb(&keys.zoom, button, state)) + if ((feh_is_bb(EVENT_zoom, button, state)) && (ev->xbutton.x == winwid->click_offset_x) && (ev->xbutton.y == winwid->click_offset_y)) { winwid->zoom = 1.0; @@ -417,7 +401,7 @@ static void feh_event_handle_ButtonRelease(XEvent * ev) winwidget_render_image(winwid, 0, 0); - } else if (feh_is_bb(&keys.blur, button, state)) { + } else if (feh_is_bb(EVENT_blur, button, state)) { D(("Disabling Blur mode\n")); opt.mode = MODE_NORMAL; winwid->mode = MODE_NORMAL; diff --git a/src/keyevents.c b/src/keyevents.c index d478a5a..f082a78 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "options.h" #include -fehkb keys; +struct __fehkey keys[EVENT_LIST_END]; struct termios old_term_settings; unsigned char control_via_stdin = 0; @@ -60,14 +60,20 @@ void restore_stdin() { eprintf("tcsetattr failed"); } -static void feh_set_kb(fehkey *key, unsigned int s0, unsigned int y0, unsigned - int s1, unsigned int y1, unsigned int s2, unsigned int y2) { +static void feh_set_kb(char *name, unsigned int s0, unsigned int y0, + unsigned int s1, unsigned int y1, unsigned int s2, unsigned int y2) { + static int key_index = 0; + fehkey *key = &keys[key_index]; key->keystates[0] = s0; key->keystates[1] = s1; key->keystates[2] = s2; key->keysyms[0] = y0; key->keysyms[1] = y1; key->keysyms[2] = y2; + key->state = 0; + key->button = 0; + key->name = name; + key_index++; } static inline int ignore_space(int keysym) { @@ -128,75 +134,82 @@ void init_keyevents(void) { FILE *conf = NULL; int read = 0; - memset(&keys, 0, sizeof(keys)); - - feh_set_kb(&keys.menu_close, 0, XK_Escape , 0, 0 , 0, 0); - feh_set_kb(&keys.menu_parent,0, XK_Left , 0, 0 , 0, 0); - feh_set_kb(&keys.menu_down , 0, XK_Down , 0, 0 , 0, 0); - feh_set_kb(&keys.menu_up , 0, XK_Up , 0, 0 , 0, 0); - feh_set_kb(&keys.menu_child, 0, XK_Right , 0, 0 , 0, 0); - feh_set_kb(&keys.menu_select,0, XK_Return , 0, XK_space , 0, 0); - feh_set_kb(&keys.scroll_left,0, XK_KP_Left , 4, XK_Left , 0, 0); - feh_set_kb(&keys.scroll_right,0,XK_KP_Right , 4, XK_Right , 0, 0); - feh_set_kb(&keys.scroll_down,0, XK_KP_Down , 4, XK_Down , 0, 0); - feh_set_kb(&keys.scroll_up , 0, XK_KP_Up , 4, XK_Up , 0, 0); - feh_set_kb(&keys.scroll_left_page , 8, XK_Left , 0, 0 , 0, 0); - feh_set_kb(&keys.scroll_right_page, 8, XK_Right, 0, 0 , 0, 0); - feh_set_kb(&keys.scroll_down_page , 8, XK_Down , 0, 0 , 0, 0); - feh_set_kb(&keys.scroll_up_page , 8, XK_Up , 0, 0 , 0, 0); - feh_set_kb(&keys.prev_img , 0, XK_Left , 0, XK_p , 0, XK_BackSpace); - feh_set_kb(&keys.next_img , 0, XK_Right , 0, XK_n , 0, XK_space); - feh_set_kb(&keys.jump_back , 0, XK_Page_Up , 0, XK_KP_Page_Up, 0, 0); - feh_set_kb(&keys.jump_fwd , 0, XK_Page_Down , 0, XK_KP_Page_Down,0,0); - feh_set_kb(&keys.prev_dir , 0, XK_bracketleft, 0, 0 , 0, 0); - feh_set_kb(&keys.next_dir , 0, XK_bracketright, 0, 0 , 0, 0); - feh_set_kb(&keys.jump_random,0, XK_z , 0, 0 , 0, 0); - feh_set_kb(&keys.quit , 0, XK_Escape , 0, XK_q , 0, 0); - feh_set_kb(&keys.close , 0, XK_x , 0, 0 , 0, 0); - feh_set_kb(&keys.remove , 0, XK_Delete , 0, 0 , 0, 0); - feh_set_kb(&keys.delete , 4, XK_Delete , 0, 0 , 0, 0); - feh_set_kb(&keys.jump_first, 0, XK_Home , 0, XK_KP_Home , 0, 0); - feh_set_kb(&keys.jump_last , 0, XK_End , 0, XK_KP_End , 0, 0); - feh_set_kb(&keys.action_0 , 0, XK_Return , 0, XK_0 , 0, XK_KP_0); - feh_set_kb(&keys.action_1 , 0, XK_1 , 0, XK_KP_1 , 0, 0); - feh_set_kb(&keys.action_2 , 0, XK_2 , 0, XK_KP_2 , 0, 0); - feh_set_kb(&keys.action_3 , 0, XK_3 , 0, XK_KP_3 , 0, 0); - feh_set_kb(&keys.action_4 , 0, XK_4 , 0, XK_KP_4 , 0, 0); - feh_set_kb(&keys.action_5 , 0, XK_5 , 0, XK_KP_5 , 0, 0); - feh_set_kb(&keys.action_6 , 0, XK_6 , 0, XK_KP_6 , 0, 0); - feh_set_kb(&keys.action_7 , 0, XK_7 , 0, XK_KP_7 , 0, 0); - feh_set_kb(&keys.action_8 , 0, XK_8 , 0, XK_KP_8 , 0, 0); - feh_set_kb(&keys.action_9 , 0, XK_9 , 0, XK_KP_9 , 0, 0); - feh_set_kb(&keys.zoom_in , 0, XK_Up , 0, XK_KP_Add , 0, 0); - feh_set_kb(&keys.zoom_out , 0, XK_Down , 0, XK_KP_Subtract,0, 0); - feh_set_kb(&keys.zoom_default, 0, XK_KP_Multiply, 0, XK_asterisk,0, 0); - feh_set_kb(&keys.zoom_fit , 0, XK_KP_Divide , 0, XK_slash , 0, 0); - feh_set_kb(&keys.zoom_fill , 0, XK_exclam , 0, 0 , 0, 0); - feh_set_kb(&keys.size_to_image, 0, XK_w , 0, 0 , 0, 0); - feh_set_kb(&keys.render , 0, XK_KP_Begin , 0, XK_R , 0, 0); - feh_set_kb(&keys.toggle_actions, 0, XK_a, 0, 0, 0, 0); - feh_set_kb(&keys.toggle_aliasing, 0, XK_A, 0, 0, 0, 0); - feh_set_kb(&keys.toggle_filenames, 0, XK_d, 0, 0, 0, 0); + /* + * The feh_set_kb statements must have the same order as the key_action + * enum. + */ + + feh_set_kb("menu_close" , 0, XK_Escape , 0, 0 , 0, 0); + feh_set_kb("menu_parent", 0, XK_Left , 0, 0 , 0, 0); + feh_set_kb("menu_down", 0, XK_Down , 0, 0 , 0, 0); + feh_set_kb("menu_up", 0, XK_Up , 0, 0 , 0, 0); + feh_set_kb("menu_child", 0, XK_Right , 0, 0 , 0, 0); + feh_set_kb("menu_select", 0, XK_Return , 0, XK_space , 0, 0); + feh_set_kb("scroll_left",0, XK_KP_Left , 4, XK_Left , 0, 0); + feh_set_kb("scroll_right", 0,XK_KP_Right , 4, XK_Right , 0, 0); + feh_set_kb("scroll_down",0, XK_KP_Down , 4, XK_Down , 0, 0); + feh_set_kb("scroll_up", 0, XK_KP_Up , 4, XK_Up , 0, 0); + feh_set_kb("scroll_left_page" , 8, XK_Left , 0, 0 , 0, 0); + feh_set_kb("scroll_right_page", 8, XK_Right, 0, 0 , 0, 0); + feh_set_kb("scroll_down_page" , 8, XK_Down , 0, 0 , 0, 0); + feh_set_kb("scroll_up_page" , 8, XK_Up , 0, 0 , 0, 0); + feh_set_kb("prev_img" , 0, XK_Left , 0, XK_p , 0, XK_BackSpace); + feh_set_kb("next_img" , 0, XK_Right , 0, XK_n , 0, XK_space); + feh_set_kb("jump_back" , 0, XK_Page_Up , 0, XK_KP_Page_Up, 0, 0); + feh_set_kb("jump_fwd" , 0, XK_Page_Down , 0, XK_KP_Page_Down,0,0); + feh_set_kb("prev_dir" , 0, XK_bracketleft, 0, 0 , 0, 0); + feh_set_kb("next_dir" , 0, XK_bracketright, 0, 0 , 0, 0); + feh_set_kb("jump_random" ,0, XK_z , 0, 0 , 0, 0); + feh_set_kb("quit" , 0, XK_Escape , 0, XK_q , 0, 0); + feh_set_kb("close" , 0, XK_x , 0, 0 , 0, 0); + feh_set_kb("remove" , 0, XK_Delete , 0, 0 , 0, 0); + feh_set_kb("delete" , 4, XK_Delete , 0, 0 , 0, 0); + feh_set_kb("jump_first" , 0, XK_Home , 0, XK_KP_Home , 0, 0); + feh_set_kb("jump_last" , 0, XK_End , 0, XK_KP_End , 0, 0); + feh_set_kb("action_0" , 0, XK_Return , 0, XK_0 , 0, XK_KP_0); + feh_set_kb("action_1" , 0, XK_1 , 0, XK_KP_1 , 0, 0); + feh_set_kb("action_2" , 0, XK_2 , 0, XK_KP_2 , 0, 0); + feh_set_kb("action_3" , 0, XK_3 , 0, XK_KP_3 , 0, 0); + feh_set_kb("action_4" , 0, XK_4 , 0, XK_KP_4 , 0, 0); + feh_set_kb("action_5" , 0, XK_5 , 0, XK_KP_5 , 0, 0); + feh_set_kb("action_6" , 0, XK_6 , 0, XK_KP_6 , 0, 0); + feh_set_kb("action_7" , 0, XK_7 , 0, XK_KP_7 , 0, 0); + feh_set_kb("action_8" , 0, XK_8 , 0, XK_KP_8 , 0, 0); + feh_set_kb("action_9" , 0, XK_9 , 0, XK_KP_9 , 0, 0); + feh_set_kb("zoom_in" , 0, XK_Up , 0, XK_KP_Add , 0, 0); + feh_set_kb("zoom_out" , 0, XK_Down , 0, XK_KP_Subtract,0, 0); + feh_set_kb("zoom_default" , 0, XK_KP_Multiply, 0, XK_asterisk,0, 0); + feh_set_kb("zoom_fit" , 0, XK_KP_Divide , 0, XK_slash , 0, 0); + feh_set_kb("zoom_fill" , 0, XK_exclam , 0, 0 , 0, 0); + feh_set_kb("size_to_image" , 0, XK_w , 0, 0 , 0, 0); + feh_set_kb("render" , 0, XK_KP_Begin , 0, XK_R , 0, 0); + feh_set_kb("toggle_actions" , 0, XK_a, 0, 0, 0, 0); + feh_set_kb("toggle_aliasing" , 0, XK_A, 0, 0, 0, 0); #ifdef HAVE_LIBEXIF - feh_set_kb(&keys.toggle_exif, 0, XK_e, 0, 0, 0, 0); + feh_set_kb("toggle_exif" , 0, XK_e, 0, 0, 0, 0); #endif - feh_set_kb(&keys.toggle_info, 0, XK_i, 0, 0, 0, 0); - feh_set_kb(&keys.toggle_pointer, 0, XK_o, 0, 0, 0, 0); - feh_set_kb(&keys.toggle_caption, 0, XK_c, 0, 0, 0, 0); - feh_set_kb(&keys.toggle_pause, 0, XK_h, 0, 0, 0, 0); - feh_set_kb(&keys.toggle_menu, 0, XK_m, 0, 0, 0, 0); - feh_set_kb(&keys.toggle_fullscreen, 0, XK_v, 0, 0, 0, 0); - feh_set_kb(&keys.reload_image, 0, XK_r, 0, 0, 0, 0); - feh_set_kb(&keys.save_image, 0, XK_s, 0, 0, 0, 0); - feh_set_kb(&keys.save_filelist, 0, XK_f, 0, 0, 0, 0); - feh_set_kb(&keys.orient_1, 0, XK_greater, 0, 0, 0, 0); - feh_set_kb(&keys.orient_3, 0, XK_less, 0, 0, 0, 0); - feh_set_kb(&keys.flip, 0, XK_underscore, 0, 0, 0, 0); - 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); - feh_set_kb(&keys.toggle_fixed_geometry, 0, XK_g, 0, 0, 0, 0); + feh_set_kb("toggle_filenames" , 0, XK_d, 0, 0, 0, 0); + feh_set_kb("toggle_info" , 0, XK_i, 0, 0, 0, 0); + feh_set_kb("toggle_pointer" , 0, XK_o, 0, 0, 0, 0); + feh_set_kb("toggle_caption" , 0, XK_c, 0, 0, 0, 0); + feh_set_kb("toggle_pause" , 0, XK_h, 0, 0, 0, 0); + feh_set_kb("toggle_menu" , 0, XK_m, 0, 0, 0, 0); + feh_set_kb("toggle_fullscreen" , 0, XK_v, 0, 0, 0, 0); + feh_set_kb("reload_image" , 0, XK_r, 0, 0, 0, 0); + feh_set_kb("save_image" , 0, XK_s, 0, 0, 0, 0); + feh_set_kb("save_filelist" , 0, XK_f, 0, 0, 0, 0); + feh_set_kb("orient_1" , 0, XK_greater, 0, 0, 0, 0); + feh_set_kb("orient_3" , 0, XK_less, 0, 0, 0, 0); + feh_set_kb("flip" , 0, XK_underscore, 0, 0, 0, 0); + feh_set_kb("mirror" , 0, XK_bar, 0, 0, 0, 0); + feh_set_kb("reload_minus" , 0, XK_minus, 0, 0, 0, 0); + feh_set_kb("reload_plus" , 0, XK_plus, 0, 0, 0, 0); + feh_set_kb("toggle_keep_vp" , 0, XK_k, 0, 0, 0, 0); + feh_set_kb("toggle_fixed_geometry" , 0, XK_g, 0, 0, 0, 0); + feh_set_kb("pan" , 0, 0, 0, 0, 0, 0); + feh_set_kb("zoom" , 0, 0, 0, 0, 0, 0); + feh_set_kb("blur" , 0, 0, 0, 0, 0, 0); + feh_set_kb("rotate" , 0, 0, 0, 0, 0, 0); home = getenv("HOME"); confhome = getenv("XDG_CONFIG_HOME"); @@ -241,21 +254,23 @@ void init_keyevents(void) { fclose(conf); } -static short feh_is_kp(fehkey *key, unsigned int state, unsigned int sym, unsigned int button) { +static short feh_is_kp(unsigned int key_index, unsigned int state, + unsigned int sym, unsigned int button) { int i; if (sym != NoSymbol) { for (i = 0; i < 3; i++) { if ( - (key->keysyms[i] == sym) && - (key->keystates[i] == state)) + (keys[key_index].keysyms[i] == sym) && + (keys[key_index].keystates[i] == state)) return 1; - else if (key->keysyms[i] == 0) + else if (keys[key_index].keysyms[i] == 0) return 0; } return 0; } - if ((key->state == state) && (key->button == button)) { + if ((keys[key_index].state == state) + && (keys[key_index].button == button)) { return 1; } return 0; @@ -352,17 +367,17 @@ void feh_event_handle_keypress(XEvent * ev) /* menus are showing, so this is a menu control keypress */ if (ev->xbutton.window == menu_cover) { selected_item = feh_menu_find_selected_r(menu_root, &selected_menu); - if (feh_is_kp(&keys.menu_close, state, keysym, 0)) + if (feh_is_kp(EVENT_menu_close, state, keysym, 0)) feh_menu_hide(menu_root, True); - else if (feh_is_kp(&keys.menu_parent, state, keysym, 0)) + else if (feh_is_kp(EVENT_menu_parent, state, keysym, 0)) feh_menu_select_parent(selected_menu); - else if (feh_is_kp(&keys.menu_down, state, keysym, 0)) + else if (feh_is_kp(EVENT_menu_down, state, keysym, 0)) feh_menu_select_next(selected_menu, selected_item); - else if (feh_is_kp(&keys.menu_up, state, keysym, 0)) + else if (feh_is_kp(EVENT_menu_up, state, keysym, 0)) feh_menu_select_prev(selected_menu, selected_item); - else if (feh_is_kp(&keys.menu_child, state, keysym, 0)) + else if (feh_is_kp(EVENT_menu_child, state, keysym, 0)) feh_menu_select_submenu(selected_menu); - else if (feh_is_kp(&keys.menu_select, state, keysym, 0)) + else if (feh_is_kp(EVENT_menu_select, state, keysym, 0)) feh_menu_item_activate(selected_menu, selected_item); return; } @@ -375,139 +390,11 @@ void feh_event_handle_keypress(XEvent * ev) fehkey *feh_str_to_kb(char *action) { - if (!strcmp(action, "menu_close")) - return &keys.menu_close; - else if (!strcmp(action, "menu_parent")) - return &keys.menu_parent; - else if (!strcmp(action, "menu_down")) - return &keys.menu_down; - else if (!strcmp(action, "menu_up")) - return &keys.menu_up; - else if (!strcmp(action, "menu_child")) - return &keys.menu_child; - else if (!strcmp(action, "menu_select")) - return &keys.menu_select; - else if (!strcmp(action, "scroll_right")) - return &keys.scroll_right; - else if (!strcmp(action, "scroll_left")) - return &keys.scroll_left; - else if (!strcmp(action, "scroll_up")) - return &keys.scroll_up; - else if (!strcmp(action, "scroll_down")) - return &keys.scroll_down; - else if (!strcmp(action, "scroll_right_page")) - return &keys.scroll_right_page; - else if (!strcmp(action, "scroll_left_page")) - return &keys.scroll_left_page; - else if (!strcmp(action, "scroll_up_page")) - return &keys.scroll_up_page; - else if (!strcmp(action, "scroll_down_page")) - return &keys.scroll_down_page; - else if (!strcmp(action, "prev_img")) - return &keys.prev_img; - else if (!strcmp(action, "next_img")) - return &keys.next_img; - else if (!strcmp(action, "jump_back")) - return &keys.jump_back; - else if (!strcmp(action, "jump_fwd")) - return &keys.jump_fwd; - else if (!strcmp(action, "prev_dir")) - return &keys.prev_dir; - else if (!strcmp(action, "next_dir")) - return &keys.next_dir; - else if (!strcmp(action, "jump_random")) - return &keys.jump_random; - else if (!strcmp(action, "quit")) - return &keys.quit; - else if (!strcmp(action, "close")) - return &keys.close; - else if (!strcmp(action, "remove")) - return &keys.remove; - else if (!strcmp(action, "delete")) - return &keys.delete; - else if (!strcmp(action, "jump_first")) - return &keys.jump_first; - else if (!strcmp(action, "jump_last")) - return &keys.jump_last; - else if (!strcmp(action, "action_0")) - return &keys.action_0; - else if (!strcmp(action, "action_1")) - return &keys.action_1; - else if (!strcmp(action, "action_2")) - return &keys.action_2; - else if (!strcmp(action, "action_3")) - return &keys.action_3; - else if (!strcmp(action, "action_4")) - return &keys.action_4; - else if (!strcmp(action, "action_5")) - return &keys.action_5; - else if (!strcmp(action, "action_6")) - return &keys.action_6; - else if (!strcmp(action, "action_7")) - return &keys.action_7; - else if (!strcmp(action, "action_8")) - return &keys.action_8; - else if (!strcmp(action, "action_9")) - return &keys.action_9; - else if (!strcmp(action, "zoom_in")) - return &keys.zoom_in; - else if (!strcmp(action, "zoom_out")) - return &keys.zoom_out; - else if (!strcmp(action, "zoom_default")) - return &keys.zoom_default; - else if (!strcmp(action, "zoom_fit")) - return &keys.zoom_fit; - else if (!strcmp(action, "zoom_fill")) - return &keys.zoom_fill; - else if (!strcmp(action, "size_to_image")) - return &keys.size_to_image; - else if (!strcmp(action, "render")) - return &keys.render; - else if (!strcmp(action, "toggle_actions")) - return &keys.toggle_actions; - else if (!strcmp(action, "toggle_aliasing")) - return &keys.toggle_aliasing; - else if (!strcmp(action, "toggle_filenames")) - return &keys.toggle_filenames; -#ifdef HAVE_LIBEXIF - else if (!strcmp(action, "toggle_exif")) - return &keys.toggle_exif; -#endif - else if (!strcmp(action, "toggle_info")) - return &keys.toggle_info; - else if (!strcmp(action, "toggle_pointer")) - return &keys.toggle_pointer; - else if (!strcmp(action, "toggle_caption")) - return &keys.toggle_caption; - else if (!strcmp(action, "toggle_pause")) - return &keys.toggle_pause; - else if (!strcmp(action, "toggle_menu")) - return &keys.toggle_menu; - else if (!strcmp(action, "toggle_fullscreen")) - return &keys.toggle_fullscreen; - else if (!strcmp(action, "reload_image")) - return &keys.reload_image; - else if (!strcmp(action, "save_image")) - return &keys.save_image; - else if (!strcmp(action, "save_filelist")) - return &keys.save_filelist; - else if (!strcmp(action, "orient_1")) - return &keys.orient_1; - else if (!strcmp(action, "orient_3")) - return &keys.orient_3; - else if (!strcmp(action, "flip")) - return &keys.flip; - else if (!strcmp(action, "mirror")) - return &keys.mirror; - else if (!strcmp(action, "reload_minus")) - return &keys.reload_minus; - else if (!strcmp(action, "reload_plus")) - return &keys.reload_plus; - else if (!strcmp(action, "toggle_keep_vp")) - return &keys.toggle_keep_vp; - else if (!strcmp(action, "toggle_fixed_geometry")) - return &keys.toggle_fixed_geometry; - + for (unsigned int i = 0; i < EVENT_LIST_END; i++) { + if (!strcmp(action, keys[i].name)) { + return &keys[i]; + } + } return NULL; } @@ -566,130 +453,130 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy return; } - if (feh_is_kp(&keys.next_img, state, keysym, button)) { + if (feh_is_kp(EVENT_next_img, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_NEXT, 1); else if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_select_next(winwid, 1); } - else if (feh_is_kp(&keys.prev_img, state, keysym, button)) { + else if (feh_is_kp(EVENT_prev_img, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_PREV, 1); else if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_select_prev(winwid, 1); } - else if (feh_is_kp(&keys.scroll_right, state, keysym, button)) { + else if (feh_is_kp(EVENT_scroll_right, state, keysym, button)) { winwid->im_x -= opt.scroll_step;; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 1); } - else if (feh_is_kp(&keys.scroll_left, state, keysym, button)) { + else if (feh_is_kp(EVENT_scroll_left, state, keysym, button)) { winwid->im_x += opt.scroll_step; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 1); } - else if (feh_is_kp(&keys.scroll_down, state, keysym, button)) { + else if (feh_is_kp(EVENT_scroll_down, state, keysym, button)) { winwid->im_y -= opt.scroll_step; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 1); } - else if (feh_is_kp(&keys.scroll_up, state, keysym, button)) { + else if (feh_is_kp(EVENT_scroll_up, state, keysym, button)) { winwid->im_y += opt.scroll_step; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 1); } - else if (feh_is_kp(&keys.scroll_right_page, state, keysym, button)) { + else if (feh_is_kp(EVENT_scroll_right_page, state, keysym, button)) { winwid->im_x -= winwid->w; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.scroll_left_page, state, keysym, button)) { + else if (feh_is_kp(EVENT_scroll_left_page, state, keysym, button)) { winwid->im_x += winwid->w; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.scroll_down_page, state, keysym, button)) { + else if (feh_is_kp(EVENT_scroll_down_page, state, keysym, button)) { winwid->im_y -= winwid->h; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.scroll_up_page, state, keysym, button)) { + else if (feh_is_kp(EVENT_scroll_up_page, state, keysym, button)) { winwid->im_y += winwid->h; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.jump_back, state, keysym, button)) { + else if (feh_is_kp(EVENT_jump_back, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_JUMP_BACK, 1); else if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_select_prev(winwid, 10); } - else if (feh_is_kp(&keys.jump_fwd, state, keysym, button)) { + else if (feh_is_kp(EVENT_jump_fwd, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_JUMP_FWD, 1); else if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_select_next(winwid, 10); } - else if (feh_is_kp(&keys.next_dir, state, keysym, button)) { + else if (feh_is_kp(EVENT_next_dir, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_JUMP_NEXT_DIR, 1); } - else if (feh_is_kp(&keys.prev_dir, state, keysym, button)) { + else if (feh_is_kp(EVENT_prev_dir, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_JUMP_PREV_DIR, 1); } - else if (feh_is_kp(&keys.quit, state, keysym, button)) { + else if (feh_is_kp(EVENT_quit, state, keysym, button)) { winwidget_destroy_all(); } - else if (feh_is_kp(&keys.delete, state, keysym, button)) { + else if (feh_is_kp(EVENT_delete, state, keysym, button)) { if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 1); feh_filelist_image_remove(winwid, 1); } - else if (feh_is_kp(&keys.remove, state, keysym, button)) { + else if (feh_is_kp(EVENT_remove, state, keysym, button)) { if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 0); feh_filelist_image_remove(winwid, 0); } - else if (feh_is_kp(&keys.jump_first, state, keysym, button)) { + else if (feh_is_kp(EVENT_jump_first, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_FIRST, 1); } - else if (feh_is_kp(&keys.jump_last, state, keysym, button)) { + else if (feh_is_kp(EVENT_jump_last, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_LAST, 1); } - else if (feh_is_kp(&keys.action_0, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_0, state, keysym, button)) { feh_event_invoke_action(winwid, 0); } - else if (feh_is_kp(&keys.action_1, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_1, state, keysym, button)) { feh_event_invoke_action(winwid, 1); } - else if (feh_is_kp(&keys.action_2, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_2, state, keysym, button)) { feh_event_invoke_action(winwid, 2); } - else if (feh_is_kp(&keys.action_3, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_3, state, keysym, button)) { feh_event_invoke_action(winwid, 3); } - else if (feh_is_kp(&keys.action_4, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_4, state, keysym, button)) { feh_event_invoke_action(winwid, 4); } - else if (feh_is_kp(&keys.action_5, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_5, state, keysym, button)) { feh_event_invoke_action(winwid, 5); } - else if (feh_is_kp(&keys.action_6, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_6, state, keysym, button)) { feh_event_invoke_action(winwid, 6); } - else if (feh_is_kp(&keys.action_7, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_7, state, keysym, button)) { feh_event_invoke_action(winwid, 7); } - else if (feh_is_kp(&keys.action_8, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_8, state, keysym, button)) { feh_event_invoke_action(winwid, 8); } - else if (feh_is_kp(&keys.action_9, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_9, state, keysym, button)) { feh_event_invoke_action(winwid, 9); } - else if (feh_is_kp(&keys.zoom_in, state, keysym, button)) { + else if (feh_is_kp(EVENT_zoom_in, state, keysym, button)) { winwid->old_zoom = winwid->zoom; winwid->zoom = winwid->zoom * 1.25; @@ -703,7 +590,7 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.zoom_out, state, keysym, button)) { + else if (feh_is_kp(EVENT_zoom_out, state, keysym, button)) { winwid->old_zoom = winwid->zoom; winwid->zoom = winwid->zoom * 0.80; @@ -717,17 +604,17 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.zoom_default, state, keysym, button)) { + else if (feh_is_kp(EVENT_zoom_default, state, keysym, button)) { winwid->zoom = 1.0; winwidget_center_image(winwid); winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.zoom_fit, state, keysym, button)) { + else if (feh_is_kp(EVENT_zoom_fit, state, keysym, button)) { feh_calc_needed_zoom(&winwid->zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h); winwidget_center_image(winwid); winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.zoom_fill, state, keysym, button)) { + else if (feh_is_kp(EVENT_zoom_fill, state, keysym, button)) { int save_zoom = opt.zoom_mode; opt.zoom_mode = ZOOM_MODE_FILL; feh_calc_needed_zoom(&winwid->zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h); @@ -735,46 +622,46 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy winwidget_render_image(winwid, 0, 0); opt.zoom_mode = save_zoom; } - else if (feh_is_kp(&keys.render, state, keysym, button)) { + else if (feh_is_kp(EVENT_render, state, keysym, button)) { if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_show_selected(); else winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.toggle_actions, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_actions, state, keysym, button)) { opt.draw_actions = !opt.draw_actions; winwidget_rerender_all(0); } - else if (feh_is_kp(&keys.toggle_aliasing, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_aliasing, state, keysym, button)) { opt.force_aliasing = !opt.force_aliasing; winwid->force_aliasing = !winwid->force_aliasing; winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.toggle_filenames, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_filenames, state, keysym, button)) { opt.draw_filename = !opt.draw_filename; winwidget_rerender_all(0); } #ifdef HAVE_LIBEXIF - else if (feh_is_kp(&keys.toggle_exif, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_exif, state, keysym, button)) { opt.draw_exif = !opt.draw_exif; winwidget_rerender_all(0); } #endif - else if (feh_is_kp(&keys.toggle_info, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_info, state, keysym, button)) { opt.draw_info = !opt.draw_info; winwidget_rerender_all(0); } - else if (feh_is_kp(&keys.toggle_pointer, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_pointer, state, keysym, button)) { winwidget_set_pointer(winwid, opt.hide_pointer); opt.hide_pointer = !opt.hide_pointer; } - else if (feh_is_kp(&keys.jump_random, state, keysym, button)) { + else if (feh_is_kp(EVENT_jump_random, state, keysym, button)) { if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_select_next(winwid, rand() % (filelist_len - 1)); else slideshow_change_image(winwid, SLIDE_RAND, 1); } - else if (feh_is_kp(&keys.toggle_caption, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_caption, state, keysym, button)) { if (opt.caption_path) { /* * editing captions in slideshow mode does not make any sense @@ -786,44 +673,44 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy } winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.reload_image, state, keysym, button)) { + else if (feh_is_kp(EVENT_reload_image, state, keysym, button)) { feh_reload_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.toggle_pause, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_pause, state, keysym, button)) { slideshow_pause_toggle(winwid); } - else if (feh_is_kp(&keys.save_image, state, keysym, button)) { + else if (feh_is_kp(EVENT_save_image, state, keysym, button)) { slideshow_save_image(winwid); } - else if (feh_is_kp(&keys.save_filelist, state, keysym, button)) { + else if (feh_is_kp(EVENT_save_filelist, state, keysym, button)) { if ((winwid->type == WIN_TYPE_THUMBNAIL) || (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)) weprintf("Filelist saving is not supported in thumbnail mode"); else feh_save_filelist(); } - else if (feh_is_kp(&keys.size_to_image, state, keysym, button)) { + else if (feh_is_kp(EVENT_size_to_image, state, keysym, button)) { winwidget_size_to_image(winwid); } - else if (!opt.no_menus && feh_is_kp(&keys.toggle_menu, state, keysym, button)) { + else if (!opt.no_menus && feh_is_kp(EVENT_toggle_menu, state, keysym, button)) { winwidget_show_menu(winwid); } - else if (feh_is_kp(&keys.close, state, keysym, button)) { + else if (feh_is_kp(EVENT_close, state, keysym, button)) { winwidget_destroy(winwid); } - else if (feh_is_kp(&keys.orient_1, state, keysym, button)) { + else if (feh_is_kp(EVENT_orient_1, state, keysym, button)) { feh_edit_inplace(winwid, 1); } - else if (feh_is_kp(&keys.orient_3, state, keysym, button)) { + else if (feh_is_kp(EVENT_orient_3, state, keysym, button)) { feh_edit_inplace(winwid, 3); } - else if (feh_is_kp(&keys.flip, state, keysym, button)) { + else if (feh_is_kp(EVENT_flip, state, keysym, button)) { feh_edit_inplace(winwid, INPLACE_EDIT_FLIP); } - else if (feh_is_kp(&keys.mirror, state, keysym, button)) { + else if (feh_is_kp(EVENT_mirror, state, keysym, button)) { feh_edit_inplace(winwid, INPLACE_EDIT_MIRROR); } - else if (feh_is_kp(&keys.toggle_fullscreen, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_fullscreen, state, keysym, button)) { #ifdef HAVE_LIBXINERAMA if (opt.xinerama && xinerama_screens) { int i, rect[4]; @@ -859,22 +746,22 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy } #endif /* HAVE_LIBXINERAMA */ } - else if (feh_is_kp(&keys.reload_plus, state, keysym, button)){ + else if (feh_is_kp(EVENT_reload_plus, state, keysym, button)){ if (opt.reload < SLIDESHOW_RELOAD_MAX) opt.reload++; else if (opt.verbose) weprintf("Cannot set RELOAD higher than %f seconds.", opt.reload); } - else if (feh_is_kp(&keys.reload_minus, state, keysym, button)) { + else if (feh_is_kp(EVENT_reload_minus, state, keysym, button)) { if (opt.reload > 1) opt.reload--; else if (opt.verbose) weprintf("Cannot set RELOAD lower than 1 second."); } - else if (feh_is_kp(&keys.toggle_keep_vp, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_keep_vp, state, keysym, button)) { opt.keep_zoom_vp = !opt.keep_zoom_vp; } - else if (feh_is_kp(&keys.toggle_fixed_geometry, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_fixed_geometry, state, keysym, button)) { if (opt.geom_flags & ((WidthValue | HeightValue))) { opt.geom_flags &= ~(WidthValue | HeightValue); } else { diff --git a/src/options.h b/src/options.h index ef7f471..4e2703e 100644 --- a/src/options.h +++ b/src/options.h @@ -134,81 +134,82 @@ struct __fehkey { unsigned int keystates[3]; unsigned int state; unsigned int button; + char *name; }; -struct __fehkb { - struct __fehkey menu_close; - struct __fehkey menu_parent; - struct __fehkey menu_down; - struct __fehkey menu_up; - struct __fehkey menu_child; - struct __fehkey menu_select; - struct __fehkey scroll_right; - struct __fehkey prev_img; - struct __fehkey scroll_left; - struct __fehkey next_img; - struct __fehkey scroll_up; - struct __fehkey scroll_down; - struct __fehkey scroll_right_page; - struct __fehkey scroll_left_page; - struct __fehkey scroll_up_page; - struct __fehkey scroll_down_page; - struct __fehkey jump_back; - struct __fehkey quit; - struct __fehkey jump_fwd; - struct __fehkey prev_dir; - struct __fehkey next_dir; - struct __fehkey remove; - struct __fehkey delete; - struct __fehkey jump_first; - struct __fehkey jump_last; - struct __fehkey action_0; - struct __fehkey action_1; - struct __fehkey action_2; - struct __fehkey action_3; - struct __fehkey action_4; - struct __fehkey action_5; - struct __fehkey action_6; - struct __fehkey action_7; - struct __fehkey action_8; - struct __fehkey action_9; - struct __fehkey zoom_in; - struct __fehkey zoom_out; - struct __fehkey zoom_default; - struct __fehkey zoom_fit; - struct __fehkey zoom_fill; - struct __fehkey render; - struct __fehkey toggle_actions; - struct __fehkey toggle_filenames; +enum key_action { + EVENT_menu_close = 0, + EVENT_menu_parent, + EVENT_menu_down, + EVENT_menu_up, + EVENT_menu_child, + EVENT_menu_select, + EVENT_scroll_left, + EVENT_scroll_right, + EVENT_scroll_down, + EVENT_scroll_up, + EVENT_scroll_left_page, + EVENT_scroll_right_page, + EVENT_scroll_down_page, + EVENT_scroll_up_page, + EVENT_prev_img, + EVENT_next_img, + EVENT_jump_back, + EVENT_jump_fwd, + EVENT_prev_dir, + EVENT_next_dir, + EVENT_jump_random, + EVENT_quit, + EVENT_close, + EVENT_remove, + EVENT_delete, + EVENT_jump_first, + EVENT_jump_last, + EVENT_action_0, + EVENT_action_1, + EVENT_action_2, + EVENT_action_3, + EVENT_action_4, + EVENT_action_5, + EVENT_action_6, + EVENT_action_7, + EVENT_action_8, + EVENT_action_9, + EVENT_zoom_in, + EVENT_zoom_out, + EVENT_zoom_default, + EVENT_zoom_fit, + EVENT_zoom_fill, + EVENT_size_to_image, + EVENT_render, + EVENT_toggle_actions, + EVENT_toggle_aliasing, #ifdef HAVE_LIBEXIF - struct __fehkey toggle_exif; + EVENT_toggle_exif, #endif - struct __fehkey toggle_info; - struct __fehkey toggle_pointer; - struct __fehkey toggle_aliasing; - struct __fehkey jump_random; - struct __fehkey toggle_caption; - struct __fehkey toggle_pause; - struct __fehkey reload_image; - struct __fehkey save_image; - struct __fehkey save_filelist; - struct __fehkey size_to_image; - struct __fehkey toggle_menu; - struct __fehkey close; - struct __fehkey orient_1; - struct __fehkey orient_3; - struct __fehkey flip; - struct __fehkey mirror; - struct __fehkey toggle_fullscreen; - struct __fehkey reload_minus; - struct __fehkey reload_plus; - struct __fehkey toggle_keep_vp; - struct __fehkey pan; - struct __fehkey zoom; - struct __fehkey reload; - struct __fehkey blur; - struct __fehkey rotate; - struct __fehkey toggle_fixed_geometry; + EVENT_toggle_filenames, + EVENT_toggle_info, + EVENT_toggle_pointer, + EVENT_toggle_caption, + EVENT_toggle_pause, + EVENT_toggle_menu, + EVENT_toggle_fullscreen, + EVENT_reload_image, + EVENT_save_image, + EVENT_save_filelist, + EVENT_orient_1, + EVENT_orient_3, + EVENT_flip, + EVENT_mirror, + EVENT_reload_minus, + EVENT_reload_plus, + EVENT_toggle_keep_vp, + EVENT_toggle_fixed_geometry, + EVENT_pan, + EVENT_zoom, + EVENT_blur, + EVENT_rotate, + EVENT_LIST_END }; void init_parse_options(int argc, char **argv); -- cgit v1.2.3 From 9b4341e12c6be32b654478cdf3a4e8a631c4e31f Mon Sep 17 00:00:00 2001 From: Niclas Zeising Date: Mon, 25 Sep 2017 18:54:24 +0200 Subject: Remove unused variable --- src/imlib.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/imlib.c b/src/imlib.c index 71b0a81..290ec8f 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -207,10 +207,6 @@ int feh_load_image(Imlib_Image * im, feh_file * file) char *tmpname = NULL; char *real_filename = NULL; -#ifdef HAVE_LIBEXIF - ExifEntry *entry; -#endif - D(("filename is %s, image is %p\n", file->filename, im)); if (!file || !file->filename) -- cgit v1.2.3 From f49f0879e651d8c92468f232febe143db2cbcd36 Mon Sep 17 00:00:00 2001 From: Niclas Zeising Date: Tue, 26 Sep 2017 21:34:56 +0200 Subject: Fix dead code The check if buffer == NULL is always false, since buffer is an autoamtic variable allocated when entering the function. What we instead want to do is to check if the string is empty after the call to exif_get_info(), since that means we could not read any exif information. When the code once more is enabled, I discovered that we need to copy the information string into info_buf as well as into buffer, since it is the former that is used to print the exif information on top of the picture. Without this change, imlib warns about trying to write NULL strings. --- src/imlib.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/imlib.c b/src/imlib.c index 290ec8f..dfb79aa 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -679,11 +679,12 @@ void feh_draw_exif(winwidget w) fn = feh_load_font(w); - if (buffer == NULL) + if (buffer[0] == '\0') { snprintf(buffer, EXIF_MAX_DATA, "%s", estrdup("Failed to run exif command")); - gib_imlib_get_text_size(fn, &buffer[0], NULL, &width, &height, IMLIB_TEXT_TO_RIGHT); - no_lines = 1; + gib_imlib_get_text_size(fn, buffer, NULL, &width, &height, IMLIB_TEXT_TO_RIGHT); + info_buf[no_lines] = estrdup(buffer); + no_lines++; } else { -- cgit v1.2.3 From 4342eab3c36ed87085fedf87bd0641889051c388 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Mon, 2 Oct 2017 18:54:36 +0200 Subject: Fix segfault when running slideshow mode with !opt.display Happens e.g. when using -O without enabling thumbnail/index mode Closes #335 --- src/main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index 605c113..840919f 100644 --- a/src/main.c +++ b/src/main.c @@ -73,11 +73,14 @@ int main(int argc, char **argv) feh_wm_set_bg_filelist(opt.bgmode); exit(0); } - else { + else if (opt.display){ /* Slideshow mode is the default. Because it's spiffy */ opt.slideshow = 1; init_slideshow_mode(); } + else { + eprintf("Invalid option combination"); + } /* main event loop */ while (feh_main_iteration(1)); -- cgit v1.2.3 From de36c62308fb982f9794db87a856fa6aae042ce6 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Tue, 3 Oct 2017 19:58:27 +0200 Subject: Make shell_escape available as a generic utility function --- src/slideshow.c | 23 ----------------------- src/utils.c | 23 +++++++++++++++++++++++ src/utils.h | 1 + 3 files changed, 24 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/slideshow.c b/src/slideshow.c index 4a71dc3..db389d5 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -464,29 +464,6 @@ void feh_action_run(feh_file * file, char *action, winwidget winwid) return; } -char *shell_escape(char *input) -{ - static char ret[1024]; - unsigned int out = 0, in = 0; - - ret[out++] = '\''; - for (in = 0; input[in] && (out < (sizeof(ret) - 7)); in++) { - if (input[in] == '\'') { - ret[out++] = '\''; - ret[out++] = '"'; - ret[out++] = '\''; - ret[out++] = '"'; - ret[out++] = '\''; - } - else - ret[out++] = input[in]; - } - ret[out++] = '\''; - ret[out++] = '\0'; - - return ret; -} - char *format_size(int size) { static char ret[5]; diff --git a/src/utils.c b/src/utils.c index dfae909..ec30d4a 100644 --- a/src/utils.c +++ b/src/utils.c @@ -201,3 +201,26 @@ char *ereadfile(char *path) return estrdup(buffer); } + +char *shell_escape(char *input) +{ + static char ret[1024]; + unsigned int out = 0, in = 0; + + ret[out++] = '\''; + for (in = 0; input[in] && (out < (sizeof(ret) - 7)); in++) { + if (input[in] == '\'') { + ret[out++] = '\''; + ret[out++] = '"'; + ret[out++] = '\''; + ret[out++] = '"'; + ret[out++] = '\''; + } + else + ret[out++] = input[in]; + } + ret[out++] = '\''; + ret[out++] = '\0'; + + return ret; +} diff --git a/src/utils.h b/src/utils.h index c0d243b..22cbbf8 100644 --- a/src/utils.h +++ b/src/utils.h @@ -46,6 +46,7 @@ char *estrjoin(const char *separator, ...); char path_is_url(char *path); char *feh_unique_filename(char *path, char *basename); char *ereadfile(char *path); +char *shell_escape(char *input); #define ESTRAPPEND(a,b) \ {\ -- cgit v1.2.3 From 528616b3df854b3bfad30c2364bf2aaf000e3a6d Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Tue, 3 Oct 2017 20:39:47 +0200 Subject: Always save user-provided commandline in ~/.fehbg This fixes --force-aliasing (and possibly other options) missing from the file. --- src/wallpaper.c | 48 +++++++----------------------------------------- 1 file changed, 7 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/wallpaper.c b/src/wallpaper.c index f40c613..e7f0b74 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -296,40 +296,11 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, Pixmap pmap_d1, pmap_d2; gib_list *l; - /* string for sticking in ~/.fehbg */ - char *fehbg = NULL; - char fehbg_args[512]; - fehbg_args[0] = '\0'; - char *argptr = fehbg_args; char *home; char filbuf[4096]; char *bgfill = NULL; bgfill = opt.image_bg == IMAGE_BG_WHITE ? "--image-bg white" : "--image-bg black" ; -#ifdef HAVE_LIBXINERAMA - if (opt.xinerama) { - if (opt.xinerama_index >= 0) { - snprintf(argptr, sizeof(fehbg_args), - "--xinerama-index %d", opt.xinerama_index); - } - } - else - snprintf(argptr, sizeof(fehbg_args), "--no-xinerama"); - argptr += strlen(argptr); -#endif /* HAVE_LIBXINERAMA */ - if ((opt.geom_flags & XValue) && (sizeof(fehbg_args) - strlen(fehbg_args) > 60)) { - snprintf(argptr, sizeof(fehbg_args) - strlen(fehbg_args), " --geometry %c%d", - opt.geom_flags & XNegative ? '-' : '+', - opt.geom_flags & XNegative ? abs(opt.geom_x) : opt.geom_x); - argptr += strlen(argptr); - if (opt.geom_flags & YValue) { - snprintf(argptr, sizeof(fehbg_args) - strlen(fehbg_args), "%c%d", - opt.geom_flags & YNegative ? '-' : '+', - opt.geom_flags & YNegative ? abs(opt.geom_y) : opt.geom_y); - argptr += strlen(argptr); - } - } - /* local display to set closedownmode on */ Display *disp2; Window root2; @@ -403,7 +374,6 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, #endif /* HAVE_LIBXINERAMA */ feh_wm_set_bg_scaled(pmap_d1, im, use_filelist, 0, 0, scr->width, scr->height); - fehbg = estrjoin(" ", "feh", fehbg_args, "--bg-scale", filbuf, NULL); } else if (centered) { D(("centering\n")); @@ -433,8 +403,6 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, XFreeGC(disp, gc); - fehbg = estrjoin(" ", "feh", fehbg_args, bgfill, "--bg-center", filbuf, NULL); - } else if (filled == 1) { pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth); @@ -464,8 +432,6 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, feh_wm_set_bg_filled(pmap_d1, im, use_filelist , 0, 0, scr->width, scr->height); - fehbg = estrjoin(" ", "feh", fehbg_args, "--bg-fill", filbuf, NULL); - } else if (filled == 2) { pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth); @@ -493,8 +459,6 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, XFreeGC(disp, gc); - fehbg = estrjoin(" ", "feh", fehbg_args, bgfill, "--bg-max", filbuf, NULL); - } else { if (use_filelist) feh_wm_load_next(&im); @@ -502,10 +466,9 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, h = gib_imlib_image_get_height(im); pmap_d1 = XCreatePixmap(disp, root, w, h, depth); gib_imlib_render_image_on_drawable(pmap_d1, im, 0, 0, 1, 0, 0); - fehbg = estrjoin(" ", "feh --bg-tile", filbuf, NULL); } - if (fehbg && !opt.no_fehbg) { + if (!opt.no_fehbg) { home = getenv("HOME"); if (home) { FILE *fp; @@ -515,7 +478,12 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, if ((fp = fopen(path, "w")) == NULL) { weprintf("Can't write to %s", path); } else { - fprintf(fp, "#!/bin/sh\n%s\n", fehbg); + fputs("#!/bin/sh\n", fp); + for (int i = 0; i < cmdargc; i++) { + fputs(shell_escape(cmdargv[i]), fp); + fputc(' ', fp); + } + fputc('\n', fp); fclose(fp); stat(path, &s); if (chmod(path, s.st_mode | S_IXUSR | S_IXGRP) != 0) { @@ -526,8 +494,6 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, } } - free(fehbg); - /* create new display, copy pixmap to new display */ disp2 = XOpenDisplay(NULL); if (!disp2) -- cgit v1.2.3 From ed0dd5a474117f337baecb2c5210ec464d120696 Mon Sep 17 00:00:00 2001 From: Marius Bakke Date: Mon, 30 Oct 2017 00:09:11 +0100 Subject: imlib: Look up CA certificates by $CURL_CA_BUNDLE. Similar to the `curl` command-line tool. --- src/imlib.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/imlib.c b/src/imlib.c index dfb79aa..82a9865 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -429,6 +429,10 @@ static char *feh_http_load_image(char *url) if (opt.insecure_ssl) { curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); + } else { + // Allow the user to specify custom CA certificates. + curl_easy_setopt(curl, CURLOPT_CAINFO, + getenv("CURL_CA_BUNDLE")); } res = curl_easy_perform(curl); -- cgit v1.2.3 From cfad4c3640d76181dcba2e1feb5bd531178c9d3e Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 1 Nov 2017 10:10:07 +0100 Subject: Fix ~/.fehbg not being updated when setting wallpaper via menu --- src/wallpaper.c | 69 +++++++++++++++++++++------------------------------------ 1 file changed, 25 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/wallpaper.c b/src/wallpaper.c index e7f0b74..222afdd 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -294,10 +294,8 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, unsigned long length, after; unsigned char *data_root = NULL, *data_esetroot = NULL; Pixmap pmap_d1, pmap_d2; - gib_list *l; char *home; - char filbuf[4096]; char *bgfill = NULL; bgfill = opt.image_bg == IMAGE_BG_WHITE ? "--image-bg white" : "--image-bg black" ; @@ -305,48 +303,10 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, Display *disp2; Window root2; int depth2; - int in, out, w, h; + int w, h; D(("Falling back to XSetRootWindowPixmap\n")); - /* Put the filename in filbuf between ' and escape ' in the filename */ - out = 0; - - if (fil && !use_filelist) { - filbuf[out++] = '\''; - - fil = feh_absolute_path(fil); - - for (in = 0; fil[in] && out < 4092; in++) { - - if (fil[in] == '\'') - filbuf[out++] = '\\'; - filbuf[out++] = fil[in]; - } - filbuf[out++] = '\''; - free(fil); - - } else { - for (l = filelist; l && out < 4092; l = l->next) { - filbuf[out++] = '\''; - - fil = feh_absolute_path(FEH_FILE(l->data)->filename); - - for (in = 0; fil[in] && out < 4092; in++) { - - if (fil[in] == '\'') - filbuf[out++] = '\\'; - filbuf[out++] = fil[in]; - } - filbuf[out++] = '\''; - filbuf[out++] = ' '; - free(fil); - } - } - - - filbuf[out++] = 0; - if (scaled) { pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth); @@ -478,10 +438,31 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, if ((fp = fopen(path, "w")) == NULL) { weprintf("Can't write to %s", path); } else { - fputs("#!/bin/sh\n", fp); - for (int i = 0; i < cmdargc; i++) { - fputs(shell_escape(cmdargv[i]), fp); + fputs("#!/bin/sh\nexec ", fp); + if (use_filelist) { + for (int i = 0; i < cmdargc; i++) { + fputs(shell_escape(cmdargv[i]), fp); + fputc(' ', fp); + } + } else if (fil) { + fputs("feh --bg-", fp); + if (centered) + fputs("center", fp); + else if (scaled) + fputs("scale", fp); + else if (filled) + fputs("fill", fp); + else + fputs("tile", fp); + + if (opt.force_aliasing) + fputs(" --force-aliasing", fp); +#ifdef HAVE_LIBXINERAMA + if (!opt.xinerama) + fputs(" --no-xinerama", fp); +#endif fputc(' ', fp); + fputs(shell_escape(fil), fp); } fputc('\n', fp); fclose(fp); -- cgit v1.2.3 From 18bf1580744c20cac6739ec3b6fb46c070320b72 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 1 Nov 2017 10:59:41 +0100 Subject: wallpaper.c: Remove unused variable --- src/wallpaper.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/wallpaper.c b/src/wallpaper.c index 222afdd..2a4743f 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -296,8 +296,6 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, Pixmap pmap_d1, pmap_d2; char *home; - char *bgfill = NULL; - bgfill = opt.image_bg == IMAGE_BG_WHITE ? "--image-bg white" : "--image-bg black" ; /* local display to set closedownmode on */ Display *disp2; -- cgit v1.2.3 From f6642257096c6fe0f78984d989790a3d9e1056fe Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Tue, 7 Nov 2017 07:52:52 +0100 Subject: Fix ~/.fehbg no longer being source-able (closes #342) --- ChangeLog | 6 ++++++ src/imlib.c | 2 +- src/wallpaper.c | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/ChangeLog b/ChangeLog index b5b814a..752b29d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Tue, 07 Nov 2017 07:51:48 +0100 + +* Release v2.22.1 + * Allow ~/.fehbg to be sourced (instead of executed) from other shell + scripts again (broken in 2.22) + Sat, 04 Nov 2017 14:55:38 +0100 Daniel Friesel * Release v2.22 diff --git a/src/imlib.c b/src/imlib.c index 82a9865..abdef4e 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -467,7 +467,7 @@ static char *feh_http_load_image(char *url) char *feh_http_load_image(char *url) { weprintf( - "Cannot load image %s\n Please recompile with libcurl support", + "Cannot load image %s\nPlease recompile feh with libcurl support", url ); return NULL; diff --git a/src/wallpaper.c b/src/wallpaper.c index 2a4743f..c9a3a05 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -436,7 +436,7 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, if ((fp = fopen(path, "w")) == NULL) { weprintf("Can't write to %s", path); } else { - fputs("#!/bin/sh\nexec ", fp); + fputs("#!/bin/sh\n", fp); if (use_filelist) { for (int i = 0; i < cmdargc; i++) { fputs(shell_escape(cmdargv[i]), fp); -- cgit v1.2.3 From edac0d1d056180ad7821ac21e09b2b53725b49f2 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Tue, 7 Nov 2017 10:36:20 +0100 Subject: Only set CURLOPT_CAINFO if CURL_CA_BUNDLE is set --- src/imlib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/imlib.c b/src/imlib.c index abdef4e..5b96e8a 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -429,7 +429,7 @@ static char *feh_http_load_image(char *url) if (opt.insecure_ssl) { curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); - } else { + } else if (getenv("CURL_CA_BUNDLE") != NULL) { // Allow the user to specify custom CA certificates. curl_easy_setopt(curl, CURLOPT_CAINFO, getenv("CURL_CA_BUNDLE")); -- cgit v1.2.3 From 8c0a881bb7fac1652a41edfba828f3d404dabcdc Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Mon, 4 Dec 2017 23:48:25 +0100 Subject: Fixed typo --- src/help.raw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/help.raw b/src/help.raw index 067e35f..2bc5986 100644 --- a/src/help.raw +++ b/src/help.raw @@ -20,7 +20,7 @@ OPTIONS -g, --geometry WxH[+X+Y] Limit the window size to DIMENSION[+OFFSET] -f, --filelist FILE Load/save images from/to the FILE filelist -|, --start-at FILENAME Start at FILENAME in the filelist - -p, --preload Remove unlaodable files from the internal filelist + -p, --preload Remove unloadable files from the internal filelist before attempting to display anything -., --scale-down Automatically scale down images to fit screen size -F, --fullscreen Make the window full screen -- cgit v1.2.3 From 402db009d2ecd17bbbc1acb6360d6164c9819316 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Thu, 7 Dec 2017 17:58:21 +0100 Subject: Disable automatic zoom adjustment of thumbnail windows Closes #351 --- src/winwidget.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/winwidget.c b/src/winwidget.c index 6f64844..81f3c4f 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -455,7 +455,7 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) || (winwid->has_rotated))) feh_draw_checks(winwid); - if (!winwid->full_screen && opt.zoom_mode + if (!winwid->full_screen && opt.zoom_mode && (winwid->type != WIN_TYPE_THUMBNAIL) && (winwid->zoom == 1.0) && ! (opt.geom_flags & (WidthValue | HeightValue)) && (winwid->w > winwid->im_w) && (winwid->h > winwid->im_h)) feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, winwid->w, winwid->h); @@ -464,14 +464,14 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) * In case of a resize, the geomflags (and im_w, im_h) get updated by * the ConfigureNotify handler. */ - if (need_center && !winwid->full_screen + if (need_center && !winwid->full_screen && (winwid->type != WIN_TYPE_THUMBNAIL) && (opt.geom_flags & (WidthValue | HeightValue)) && ((winwid->w < winwid->im_w) || (winwid->h < winwid->im_h))) feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, winwid->w, winwid->h); - if (resize && (winwid->full_screen - || (opt.geom_flags & (WidthValue | HeightValue)))) { + if (resize && (winwid->type != WIN_TYPE_THUMBNAIL) && + (winwid->full_screen || (opt.geom_flags & (WidthValue | HeightValue)))) { int smaller; /* Is the image smaller than screen? */ int max_w = 0, max_h = 0; -- cgit v1.2.3 From c59aafb5b3f6a8063e24c53042be178ada155552 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Thu, 7 Dec 2017 18:49:42 +0100 Subject: Compile with std=c11 and set appropriate glibc feature test macros might resolve #333 and #348 --- config.mk | 3 +++ src/gib_hash.c | 1 + src/options.c | 1 + 3 files changed, 5 insertions(+) (limited to 'src') diff --git a/config.mk b/config.mk index b230e3d..394a13f 100644 --- a/config.mk +++ b/config.mk @@ -37,6 +37,9 @@ scalable_icon_dir = ${icon_dir}/scalable/apps CFLAGS ?= -g -O2 CFLAGS += -Wall -Wextra -pedantic +# Settings for glibc >= 2.19 - may need to be adjusted for other systems +CFLAGS += -std=c11 -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=500 + ifeq (${curl},1) CFLAGS += -DHAVE_LIBCURL LDLIBS += -lcurl diff --git a/src/gib_hash.c b/src/gib_hash.c index a378b9c..15bbf4a 100644 --- a/src/gib_hash.c +++ b/src/gib_hash.c @@ -26,6 +26,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "gib_hash.h" #include "utils.h" #include "debug.h" +#include gib_hash_node *gib_hash_node_new(char *key, void *data) { diff --git a/src/options.c b/src/options.c index 4f87685..1ed5b54 100644 --- a/src/options.c +++ b/src/options.c @@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "feh.h" #include "filelist.h" #include "options.h" +#include static void check_options(void); static void feh_getopt_theme(int argc, char **argv); -- cgit v1.2.3 From a398b0d16faec1a08ce793e88edf5f9fb101624c Mon Sep 17 00:00:00 2001 From: ulteq Date: Wed, 27 Dec 2017 18:58:13 +0100 Subject: Utilize the imlib cache properly This prevents removing the image data from the cache, when moving back and forth between images. As suggested by the Imlib documentation: http://alien.cern.ch/cache/imlib2-1.0.6/doc/ --- src/winwidget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/winwidget.c b/src/winwidget.c index 81f3c4f..7ee63c2 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -1008,7 +1008,7 @@ void winwidget_rename(winwidget winwid, char *newname) void winwidget_free_image(winwidget w) { if (w->im) - gib_imlib_free_image_and_decache(w->im); + gib_imlib_free_image(w->im); w->im = NULL; w->im_w = 0; w->im_h = 0; -- cgit v1.2.3 From 0a006ed6767e42bbc1608400faf0fa9e008ff49c Mon Sep 17 00:00:00 2001 From: ulteq Date: Wed, 27 Dec 2017 19:03:03 +0100 Subject: Add option to change the imlib cache size This option allows you to change the default imlib2 image cache size of 4 MiB. --- src/help.raw | 1 + src/imlib.c | 2 ++ src/options.c | 10 ++++++++++ src/options.h | 3 +++ 4 files changed, 16 insertions(+) (limited to 'src') diff --git a/src/help.raw b/src/help.raw index 2bc5986..37e0e71 100644 --- a/src/help.raw +++ b/src/help.raw @@ -94,6 +94,7 @@ OPTIONS --min-dimension WxH Only show images with width >= W and height >= H --max-dimension WxH Only show images with width <= W and height <= H --scroll-step COUNT scroll COUNT pixels when movement key is pressed + --cache-size NUM imlib cache size in mebibytes (0 .. 2048) MONTAGE MODE OPTIONS -X, --ignore-aspect Set thumbnail to specified width/height without diff --git a/src/imlib.c b/src/imlib.c index 5b96e8a..48808a1 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -131,6 +131,8 @@ void init_x_and_imlib(void) imlib_context_set_operation(IMLIB_OP_COPY); wmDeleteWindow = XInternAtom(disp, "WM_DELETE_WINDOW", False); + imlib_set_cache_size(opt.cache_size * 1024 * 1024); + /* Initialise random numbers */ srand(getpid() * time(NULL) % ((unsigned int) -1)); diff --git a/src/options.c b/src/options.c index 1ed5b54..c874832 100644 --- a/src/options.c +++ b/src/options.c @@ -68,6 +68,7 @@ void init_parse_options(int argc, char **argv) opt.jump_on_resort = 1; opt.screen_clip = 1; + opt.cache_size = 4; #ifdef HAVE_LIBXINERAMA /* if we're using xinerama, then enable it by default */ opt.xinerama = 1; @@ -410,6 +411,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"xinerama-index", 1, 0, 239}, {"insecure" , 0, 0, 240}, {"no-recursive" , 0, 0, 241}, + {"cache-size" , 1, 0, 243}, {0, 0, 0, 0} }; int optch = 0, cmdx = 0; @@ -772,6 +774,14 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) break; case 241: opt.recursive = 0; + break; + case 243: + opt.cache_size = atoi(optarg); + if (opt.cache_size < 0) + opt.cache_size = 0; + if (opt.cache_size > 2048) + opt.cache_size = 2048; + break; default: break; } diff --git a/src/options.h b/src/options.h index 4e2703e..c6959c8 100644 --- a/src/options.h +++ b/src/options.h @@ -117,6 +117,9 @@ struct __fehoptions { /* signed in case someone wants to invert scrolling real quick */ int scroll_step; + // imlib cache size in mebibytes + int cache_size; + unsigned int min_width, min_height, max_width, max_height; unsigned char mode; -- cgit v1.2.3 From b6e1da781e80eb901e76cdfe95a09fa84116496e Mon Sep 17 00:00:00 2001 From: ulteq Date: Thu, 28 Dec 2017 19:03:10 +0100 Subject: Apply the toggle_fixed_geometry event to current image --- src/keyevents.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/keyevents.c b/src/keyevents.c index f082a78..c6f5527 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -769,6 +769,7 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy opt.geom_w = winwid->w; opt.geom_h = winwid->h; } + winwidget_render_image(winwid, 1, 0); } return; } -- cgit v1.2.3 From 91b331f0fa6999dff69fa1da90a8816b8d855ccc Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Thu, 28 Dec 2017 19:04:20 +0100 Subject: Always check file modification time before loading images from cache --- src/imlib.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/imlib.c b/src/imlib.c index 48808a1..73b7039 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -256,6 +256,16 @@ int feh_load_image(Imlib_Image * im, feh_file * file) return(0); } + /* + * By default, Imlib2 unconditionally loads a cached file without checking + * if it was modified on disk. However, feh (or rather its users) should + * expect image changes to appear at the next reload. So we tell Imlib2 to + * always check the file modification time and only use a cached image if + * the mtime was not changed. The performance penalty is usually negligible. + */ + imlib_context_set_image(*im); + imlib_image_set_changes_on_disk(); + #ifdef HAVE_LIBEXIF int orientation = 0; ExifData *exifData = exif_data_new_from_file(file->filename); -- cgit v1.2.3 From a06eae174885e998031dd179457a0faafa545c59 Mon Sep 17 00:00:00 2001 From: ulteq Date: Thu, 28 Dec 2017 19:12:52 +0100 Subject: Only calculate needed zoom when necessary This will prevent unnecessary calls to 'feh_calc_needed_zoom' --- src/winwidget.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/winwidget.c b/src/winwidget.c index 7ee63c2..d636a85 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -498,12 +498,6 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) && (winwid->im_h < max_h)); if (!smaller || opt.zoom_mode) { - double ratio = 0.0; - - /* Image is larger than the screen (so wants shrinking), or it's - smaller but wants expanding to fill it */ - ratio = feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, max_w, max_h); - /* contributed by Jens Laas * What it does: * zooms images by a fixed amount but never larger than the screen. @@ -535,6 +529,10 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) winwid->im_y = ((int) (max_h - (winwid->im_h * winwid->zoom))) >> 1; } else { + /* Image is larger than the screen (so wants shrinking), or it's + smaller but wants expanding to fill it */ + double ratio = feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, max_w, max_h); + if (ratio > 1.0) { /* height is the factor */ winwid->im_x = 0; -- cgit v1.2.3 From d1cffb065667e9d96fb6a03b3fcda5a9543f8d0c Mon Sep 17 00:00:00 2001 From: Olof-Joachim Frahm Date: Wed, 3 Jan 2018 00:51:38 +0100 Subject: Add files from file list file on reload. Fixes issue 325. --- src/slideshow.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/slideshow.c b/src/slideshow.c index db389d5..4e58596 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -110,6 +110,10 @@ void cb_reload_timer(void *data) add_file_to_filelist_recursively(l->data, FILELIST_FIRST); else if (!opt.filelistfile && !opt.bgmode) add_file_to_filelist_recursively(".", FILELIST_FIRST); + + if (opt.filelistfile) { + filelist = gib_list_cat(filelist, feh_read_filelist(opt.filelistfile)); + } if (!(filelist_len = gib_list_length(filelist))) { eprintf("No files found to reload."); -- cgit v1.2.3 From 4169eae19a75ce5c1f94f69bcee5ce2e3bed78f7 Mon Sep 17 00:00:00 2001 From: Max Rees Date: Sat, 6 Jan 2018 23:59:18 -0500 Subject: fflush in src/list.c to make tested behavior consistent On glibc, if output is redirected to a file, output will look like this: touch test/ok/gif touch test/ok/jpg touch test/ok/png touch test/ok/pnm test/ok/gif test/ok/jpg test/ok/png test/ok/pnm On musl, if stdout is redirected to a file, output looks like this: test/ok/gif touch test/ok/gif touch test/ok/jpg touch test/ok/png touch test/ok/pnm test/ok/jpg test/ok/png test/ok/pnm On glibc and musl, if stdout is interactive, it looks like this: test/ok/gif touch test/ok/gif test/ok/jpg touch test/ok/jpg test/ok/png touch test/ok/png test/ok/pnm touch test/ok/pnm Adding two fflush calls makes all behavior look like the last example. Test cases have been updated accordingly. --- src/list.c | 2 ++ test/nx_action/loadable_action | 8 ++++---- test/nx_action/loadable_naction | 8 ++++---- test/nx_action/unloadable_action | 8 ++++---- test/nx_action/unloadable_naction | 8 ++++---- 5 files changed, 18 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/list.c b/src/list.c index 6f317c4..09b23f4 100644 --- a/src/list.c +++ b/src/list.c @@ -92,6 +92,7 @@ void real_loadables_mode(int loadable) if (opt.verbose) feh_display_status('.'); puts(file->filename); + fflush(stdout); feh_action_run(file, opt.actions[0], NULL); } else { @@ -106,6 +107,7 @@ void real_loadables_mode(int loadable) if (opt.verbose) feh_display_status('.'); puts(file->filename); + fflush(stdout); feh_action_run(file, opt.actions[0], NULL); } else { diff --git a/test/nx_action/loadable_action b/test/nx_action/loadable_action index d173261..fbf517b 100644 --- a/test/nx_action/loadable_action +++ b/test/nx_action/loadable_action @@ -1,8 +1,8 @@ -touch test/ok/gif -touch test/ok/jpg -touch test/ok/png -touch test/ok/pnm test/ok/gif +touch test/ok/gif test/ok/jpg +touch test/ok/jpg test/ok/png +touch test/ok/png test/ok/pnm +touch test/ok/pnm diff --git a/test/nx_action/loadable_naction b/test/nx_action/loadable_naction index d173261..fbf517b 100644 --- a/test/nx_action/loadable_naction +++ b/test/nx_action/loadable_naction @@ -1,8 +1,8 @@ -touch test/ok/gif -touch test/ok/jpg -touch test/ok/png -touch test/ok/pnm test/ok/gif +touch test/ok/gif test/ok/jpg +touch test/ok/jpg test/ok/png +touch test/ok/png test/ok/pnm +touch test/ok/pnm diff --git a/test/nx_action/unloadable_action b/test/nx_action/unloadable_action index c16572e..cdf3ed8 100644 --- a/test/nx_action/unloadable_action +++ b/test/nx_action/unloadable_action @@ -1,8 +1,8 @@ -rm test/fail/gif -rm test/fail/jpg -rm test/fail/png -rm test/fail/pnm test/fail/gif +rm test/fail/gif test/fail/jpg +rm test/fail/jpg test/fail/png +rm test/fail/png test/fail/pnm +rm test/fail/pnm diff --git a/test/nx_action/unloadable_naction b/test/nx_action/unloadable_naction index c16572e..cdf3ed8 100644 --- a/test/nx_action/unloadable_naction +++ b/test/nx_action/unloadable_naction @@ -1,8 +1,8 @@ -rm test/fail/gif -rm test/fail/jpg -rm test/fail/png -rm test/fail/pnm test/fail/gif +rm test/fail/gif test/fail/jpg +rm test/fail/jpg test/fail/png +rm test/fail/png test/fail/pnm +rm test/fail/pnm -- cgit v1.2.3 From b9b84ee55d6b255bcf39a4f8ca6195749ef1fc5c Mon Sep 17 00:00:00 2001 From: ulteq Date: Sun, 14 Jan 2018 17:20:14 +0100 Subject: Handle --min-dimension and --max-dimension without preload This will (by default) check the image dimension on-the-fly, but you can still do it beforehand by specifying the preload flag. --- src/filelist.c | 4 +--- src/slideshow.c | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/filelist.c b/src/filelist.c index b569b8a..0066efd 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -464,9 +464,7 @@ int feh_cmp_format(void *file1, void *file2) void feh_prepare_filelist(void) { - 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)) { + if (opt.list || opt.preload || opt.customlist || (opt.sort > SORT_MTIME)) { /* For these sort options, we have to preload images */ filelist = feh_file_info_preload(filelist); if (!gib_list_length(filelist)) diff --git a/src/slideshow.c b/src/slideshow.c index db389d5..3d73d8e 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -378,16 +378,22 @@ void slideshow_change_image(winwidget winwid, int change, int render) tzoom = winwid->zoom; } - if ((winwidget_loadimage(winwid, FEH_FILE(current_file->data))) - != 0) { + if (winwidget_loadimage(winwid, FEH_FILE(current_file->data))) { + unsigned int w = gib_imlib_image_get_width(winwid->im); + unsigned int h = gib_imlib_image_get_height(winwid->im); + if (opt.min_width || opt.min_height || (opt.max_width != UINT_MAX) || (opt.max_height != UINT_MAX)) { + if (w < opt.min_width || w > opt.max_width || h < opt.min_height || h > opt.max_height) { + last = current_file; + continue; + } + } winwid->mode = MODE_NORMAL; winwid->file = current_file; - if ((winwid->im_w != gib_imlib_image_get_width(winwid->im)) - || (winwid->im_h != gib_imlib_image_get_height(winwid->im))) + if ((winwid->im_w != (int)w) || (winwid->im_h != (int)h)) winwid->had_resize = 1; winwidget_reset_image(winwid); - winwid->im_w = gib_imlib_image_get_width(winwid->im); - winwid->im_h = gib_imlib_image_get_height(winwid->im); + winwid->im_w = w; + winwid->im_h = h; if (opt.keep_zoom_vp) { /* put back in: */ winwid->mode = tmode; -- cgit v1.2.3 From 5965739a0aa6e1f91989a011746c2709cb4e92dc Mon Sep 17 00:00:00 2001 From: Paul O'Day Date: Tue, 26 Mar 2013 20:52:14 -0700 Subject: Allow any XColor values as --image-bg argument --- man/feh.pre | 2 +- src/feh.h | 2 -- src/help.raw | 2 +- src/options.c | 9 +-------- src/options.h | 2 +- src/wallpaper.c | 29 ++++++++++++----------------- src/winwidget.c | 26 ++++++++++++++------------ 7 files changed, 30 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/man/feh.pre b/man/feh.pre index c2a4cd1..90e6b20 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -379,7 +379,7 @@ Hide the pointer .It Cm -B , --image-bg Ar style . Use style as background for transparent image parts and the like. -Accepted values: checks, white, black. +Accepted values: default, checks, or a XColor (eg. #428bdd). . The default for windowed mode is checks, while fullscreen defaults to black. . diff --git a/src/feh.h b/src/feh.h index a4a0a7b..3f0ce0c 100644 --- a/src/feh.h +++ b/src/feh.h @@ -107,8 +107,6 @@ enum slide_change { SLIDE_NEXT, SLIDE_PREV, SLIDE_RAND, SLIDE_FIRST, SLIDE_LAST, SLIDE_JUMP_PREV_DIR }; -enum image_bg { IMAGE_BG_CHECKS = 1, IMAGE_BG_BLACK, IMAGE_BG_WHITE }; - #define INPLACE_EDIT_FLIP -1 #define INPLACE_EDIT_MIRROR -2 diff --git a/src/help.raw b/src/help.raw index 37e0e71..8b244c1 100644 --- a/src/help.raw +++ b/src/help.raw @@ -84,7 +84,7 @@ OPTIONS can be used multiple times to add multiple paths. -M, --menu-font FONT Use FONT for the font in menus. -B, --image-bg STYLE Set background for transparent images and the like. - Accepted values: white, black, default + Accepted values: default, checks, or a XColor (eg. #428bdd) -N, --no-menus Don't load or show any menus. --no-xinerama Disable Xinerama support --no-screen-clip Do not limit window size to screen size diff --git a/src/options.c b/src/options.c index c874832..03f5ae3 100644 --- a/src/options.c +++ b/src/options.c @@ -449,14 +449,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) 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); + opt.image_bg = estrdup(optarg); break; case 'C': D(("adding fontpath %s\n", optarg)); diff --git a/src/options.h b/src/options.h index c6959c8..fc9774e 100644 --- a/src/options.h +++ b/src/options.h @@ -71,7 +71,6 @@ struct __fehoptions { unsigned char cycle_once; unsigned char hold_actions[10]; unsigned char text_bg; - unsigned char image_bg; unsigned char no_fehbg; unsigned char keep_zoom_vp; unsigned char insecure_ssl; @@ -79,6 +78,7 @@ struct __fehoptions { char *output_file; char *output_dir; char *bg_file; + char *image_bg; char *font; char *title_font; char *title; diff --git a/src/wallpaper.c b/src/wallpaper.c index c9a3a05..5c50ad8 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -305,15 +305,19 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, D(("Falling back to XSetRootWindowPixmap\n")); + XColor color; + Colormap cmap = DefaultColormap(disp, DefaultScreen(disp)); + if (opt.image_bg) + XAllocNamedColor(disp, cmap, (char*) opt.image_bg, &color, &color); + else + XAllocNamedColor(disp, cmap, "black", &color, &color); + if (scaled) { pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth); #ifdef HAVE_LIBXINERAMA if (opt.xinerama_index >= 0) { - if (opt.image_bg == IMAGE_BG_WHITE) - gcval.foreground = WhitePixel(disp, DefaultScreen(disp)); - else - gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); + gcval.foreground = color.pixel; gc = XCreateGC(disp, root, GCForeground, &gcval); XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height); XFreeGC(disp, gc); @@ -337,10 +341,7 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, D(("centering\n")); pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth); - if (opt.image_bg == IMAGE_BG_WHITE) - gcval.foreground = WhitePixel(disp, DefaultScreen(disp)); - else - gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); + gcval.foreground = color.pixel; gc = XCreateGC(disp, root, GCForeground, &gcval); XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height); @@ -367,10 +368,7 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, #ifdef HAVE_LIBXINERAMA if (opt.xinerama_index >= 0) { - if (opt.image_bg == IMAGE_BG_WHITE) - gcval.foreground = WhitePixel(disp, DefaultScreen(disp)); - else - gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); + gcval.foreground = color.pixel; gc = XCreateGC(disp, root, GCForeground, &gcval); XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height); XFreeGC(disp, gc); @@ -393,10 +391,7 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, } else if (filled == 2) { pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth); - if (opt.image_bg == IMAGE_BG_WHITE) - gcval.foreground = WhitePixel(disp, DefaultScreen(disp)); - else - gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); + gcval.foreground = color.pixel; gc = XCreateGC(disp, root, GCForeground, &gcval); XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height); @@ -472,7 +467,7 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, free(path); } } - + /* create new display, copy pixmap to new display */ disp2 = XOpenDisplay(NULL); if (!disp2) diff --git a/src/winwidget.c b/src/winwidget.c index d636a85..e0796fa 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -391,17 +391,18 @@ void winwidget_setup_pixmaps(winwidget winwid) if (winwid->gc == None) { XGCValues gcval; - if (opt.image_bg == IMAGE_BG_WHITE) { - gcval.foreground = WhitePixel(disp, DefaultScreen(disp)); + if (!opt.image_bg || !strcmp(opt.image_bg, "default")) { + gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); winwid->gc = XCreateGC(disp, winwid->win, GCForeground, &gcval); - } - else if (opt.image_bg == IMAGE_BG_CHECKS) { + } else if (!strcmp(opt.image_bg, "checks")) { gcval.tile = feh_create_checks(); gcval.fill_style = FillTiled; winwid->gc = XCreateGC(disp, winwid->win, GCTile | GCFillStyle, &gcval); - } - else { - gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); + } else { + XColor color; + Colormap cmap = DefaultColormap(disp, DefaultScreen(disp)); + XAllocNamedColor(disp, cmap, (char*) opt.image_bg, &color, &color); + gcval.foreground = color.pixel; winwid->gc = XCreateGC(disp, winwid->win, GCForeground, &gcval); } } @@ -700,14 +701,15 @@ Pixmap feh_create_checks(void) if (!checks) eprintf("Unable to create a teeny weeny imlib image. I detect problems"); - if (opt.image_bg == IMAGE_BG_WHITE) - gib_imlib_image_fill_rectangle(checks, 0, 0, 16, 16, 255, 255, 255, 255); - else if (opt.image_bg == IMAGE_BG_BLACK) - gib_imlib_image_fill_rectangle(checks, 0, 0, 16, 16, 0, 0, 0, 255); - else { + if (!opt.image_bg || !strcmp(opt.image_bg, "default") || !strcmp(opt.image_bg, "checks")) { gib_imlib_image_fill_rectangle(checks, 0, 0, 16, 16, 144, 144, 144, 255); gib_imlib_image_fill_rectangle(checks, 0, 0, 8, 8, 100, 100, 100, 255); gib_imlib_image_fill_rectangle(checks, 8, 8, 8, 8, 100, 100, 100, 255); + } else { + XColor color; + Colormap cmap = DefaultColormap(disp, DefaultScreen(disp)); + XAllocNamedColor(disp, cmap, (char*) opt.image_bg, &color, &color); + gib_imlib_image_fill_rectangle(checks, 0, 0, 16, 16, color.red, color.green, color.blue, 255); } checks_pmap = XCreatePixmap(disp, root, 16, 16, depth); -- cgit v1.2.3 From c8a4e7daa32b6fccd58a64bdad32773a055f8811 Mon Sep 17 00:00:00 2001 From: ulteq Date: Fri, 19 Jan 2018 19:03:43 +0100 Subject: Removes unnecessary code Halves the start-up time of the slideshow if the title contains data from 'file->info' --- src/slideshow.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src') diff --git a/src/slideshow.c b/src/slideshow.c index db389d5..80fa918 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -35,9 +35,7 @@ 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)) { @@ -52,15 +50,12 @@ void init_slideshow_mode(void) 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); + if ((w = winwidget_create_from_file(l, NULL, WIN_TYPE_SLIDESHOW)) != NULL) { success = 1; winwidget_show(w); if (opt.slideshow_delay > 0.0) @@ -69,7 +64,6 @@ void init_slideshow_mode(void) feh_add_unique_timer(cb_reload_timer, w, opt.reload); break; } else { - free(s); last = l; } } -- cgit v1.2.3 From 394517d1c66783c4e1d044f79df9ef1703a6f5db Mon Sep 17 00:00:00 2001 From: ulteq Date: Sat, 20 Jan 2018 11:25:09 +0100 Subject: Fix the --magick-timeout handling * Prevents nasty loading loops * Prevents zombie subprocesses * Fixes the conversion timeout detection routine --- src/imlib.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/imlib.c b/src/imlib.c index 73b7039..6de6bdb 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -231,7 +231,7 @@ int feh_load_image(Imlib_Image * im, feh_file * file) if ((image_source != SRC_IMLIB) && tmpname) { *im = imlib_load_image_with_error_return(tmpname, &err); - if (im) { + if (!err && im) { real_filename = file->filename; file->filename = tmpname; feh_file_info_load(file, *im); @@ -240,7 +240,7 @@ int feh_load_image(Imlib_Image * im, feh_file * file) file->ed = exif_get_data(tmpname); #endif } - if ((image_source == SRC_MAGICK) || !opt.keep_http) + if ((image_source != SRC_HTTP) || !opt.keep_http) unlink(tmpname); free(tmpname); @@ -357,30 +357,17 @@ static char *feh_magick_load_image(char *filename) else { alarm(opt.magick_timeout); waitpid(childpid, &status, 0); - alarm(0); - if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { - close(fd); + kill(childpid, SIGKILL); + if (opt.magick_timeout > 0 && !alarm(0)) { unlink(sfn); free(sfn); sfn = NULL; if (!opt.quiet) { - if (WIFSIGNALED(status)) - weprintf("%s - Conversion took too long, skipping", - filename); + weprintf("%s - Conversion took too long, skipping", filename); } - - /* - * Reap child. The previous waitpid call was interrupted by - * alarm, but convert doesn't terminate immediately. - * XXX - * normally, if (WIFSIGNALED(status)) waitpid(childpid, &status, 0); - * would suffice. However, as soon as feh has its own window, - * this doesn't work anymore and the following workaround is - * required. Hm. - */ - waitpid(-1, &status, 0); } + close(fd); childpid = 0; } -- cgit v1.2.3 From 7acf83ea6d6f36e418f43a3408632944fbb7bcde Mon Sep 17 00:00:00 2001 From: ulteq Date: Thu, 18 Jan 2018 11:07:45 +0100 Subject: Add natural sort of (version) numbers --- src/feh.h | 1 + src/filelist.c | 19 +++++++++++++++---- src/help.raw | 1 + src/options.c | 4 ++++ src/options.h | 1 + 5 files changed, 22 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/feh.h b/src/feh.h index a4a0a7b..da08aba 100644 --- a/src/feh.h +++ b/src/feh.h @@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef FEH_H #define FEH_H +#define _GNU_SOURCE #include #include #include diff --git a/src/filelist.c b/src/filelist.c index b569b8a..3157e32 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -399,12 +399,18 @@ void feh_file_dirname(char *dst, feh_file * f, int maxlen) int feh_cmp_filename(void *file1, void *file2) { - return(strcmp(FEH_FILE(file1)->filename, FEH_FILE(file2)->filename)); + if (!opt.version_sort) + return(strcmp(FEH_FILE(file1)->filename, FEH_FILE(file2)->filename)); + else + return(strverscmp(FEH_FILE(file1)->filename, FEH_FILE(file2)->filename)); } int feh_cmp_name(void *file1, void *file2) { - return(strcmp(FEH_FILE(file1)->name, FEH_FILE(file2)->name)); + if (!opt.version_sort) + return(strcmp(FEH_FILE(file1)->name, FEH_FILE(file2)->name)); + else + return(strverscmp(FEH_FILE(file1)->name, FEH_FILE(file2)->name)); } int feh_cmp_dirname(void *file1, void *file2) @@ -413,8 +419,13 @@ int feh_cmp_dirname(void *file1, void *file2) int cmp; feh_file_dirname(dir1, FEH_FILE(file1), PATH_MAX); feh_file_dirname(dir2, FEH_FILE(file2), PATH_MAX); - if ((cmp = strcmp(dir1, dir2)) != 0) - return(cmp); + if (!opt.version_sort) { + if ((cmp = strcmp(dir1, dir2)) != 0) + return(cmp); + } else { + if ((cmp = strverscmp(dir1, dir2)) != 0) + return(cmp); + } return(feh_cmp_name(file1, file2)); } diff --git a/src/help.raw b/src/help.raw index 37e0e71..8c83b5b 100644 --- a/src/help.raw +++ b/src/help.raw @@ -52,6 +52,7 @@ OPTIONS name, filename, mtime, width, height, pixels, size, or format -n, --reverse Reverse sort order + --version-sort Natural sort of (version) numbers within text -A, --action [;]ACTION Specify action to perform when pressing . Executed by /bin/sh, may contain FORMAT SPECIFIERS reloads image with \";\", switches to next otherwise diff --git a/src/options.c b/src/options.c index c874832..3fcbdef 100644 --- a/src/options.c +++ b/src/options.c @@ -412,6 +412,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"insecure" , 0, 0, 240}, {"no-recursive" , 0, 0, 241}, {"cache-size" , 1, 0, 243}, + {"version-sort" , 0, 0, 246}, {0, 0, 0, 0} }; int optch = 0, cmdx = 0; @@ -782,6 +783,9 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) if (opt.cache_size > 2048) opt.cache_size = 2048; break; + case 246: + opt.version_sort = 1; + break; default: break; } diff --git a/src/options.h b/src/options.h index c6959c8..277cede 100644 --- a/src/options.h +++ b/src/options.h @@ -103,6 +103,7 @@ struct __fehoptions { unsigned int thumb_redraw; double reload; int sort; + int version_sort; int debug; int geom_flags; int geom_x; -- cgit v1.2.3 From 5dc0d6770bc46676b969b60cc81f8ee689aaf829 Mon Sep 17 00:00:00 2001 From: ulteq Date: Wed, 24 Jan 2018 12:00:57 +0100 Subject: Simplify window title generation --- src/collage.c | 12 ++---------- src/feh.h | 2 -- src/index.c | 12 ++---------- src/multiwindow.c | 20 ++++---------------- src/slideshow.c | 56 +++++++++---------------------------------------------- src/thumbnail.c | 38 ++++++------------------------------- src/winwidget.c | 29 ++++++++-------------------- src/winwidget.h | 4 ++-- 8 files changed, 33 insertions(+), 140 deletions(-) (limited to 'src') diff --git a/src/collage.c b/src/collage.c index b975136..431d3b6 100644 --- a/src/collage.c +++ b/src/collage.c @@ -41,7 +41,6 @@ void init_collage_mode(void) feh_file *file = NULL; unsigned char trans_bg = 0; gib_list *l, *last = NULL; - char *s; mode = "collage"; @@ -105,15 +104,9 @@ void init_collage_mode(void) gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h, 0, 0, 0, 255); } - /* Create the title string */ - - if (!opt.title) - s = estrdup(PACKAGE " [collage mode]"); - else - s = estrdup(feh_printf(opt.title, NULL, NULL)); - if (opt.display) { - winwid = winwidget_create_from_image(im_main, s, WIN_TYPE_SINGLE); + winwid = winwidget_create_from_image(im_main, WIN_TYPE_SINGLE); + winwidget_rename(winwid, PACKAGE " [collage mode]"); winwidget_show(winwid); } @@ -210,7 +203,6 @@ void init_collage_mode(void) if (!opt.display) gib_imlib_free_image_and_decache(im_main); - free(s); return; } diff --git a/src/feh.h b/src/feh.h index a4a0a7b..bfd71db 100644 --- a/src/feh.h +++ b/src/feh.h @@ -137,8 +137,6 @@ int feh_load_image(Imlib_Image * im, feh_file * file); void show_mini_usage(void); void slideshow_change_image(winwidget winwid, int change, int render); void slideshow_pause_toggle(winwidget w); -char *slideshow_create_name(feh_file * file, winwidget winwid); -char *thumbnail_create_name(feh_file * file, winwidget winwid); void init_keyevents(void); void init_buttonbindings(void); void setup_stdin(void); diff --git a/src/index.c b/src/index.c index fbc25b8..c8c34c5 100644 --- a/src/index.c +++ b/src/index.c @@ -59,7 +59,6 @@ void init_index_mode(void) int lineno; unsigned char trans_bg = 0; int index_image_width, index_image_height; - char *s; gib_list *line, *lines; if (opt.montage) { @@ -164,15 +163,9 @@ void init_index_mode(void) gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h + title_area_h, 0, 0, 0, 255); } - /* Create the window title at this point */ - - if (!opt.title) - s = estrdup(PACKAGE " [index mode]"); - else - s = estrdup(feh_printf(opt.title, NULL, NULL)); - if (opt.display) { - winwid = winwidget_create_from_image(im_main, s, WIN_TYPE_SINGLE); + winwid = winwidget_create_from_image(im_main, WIN_TYPE_SINGLE); + winwidget_rename(winwid, PACKAGE " [index mode]"); winwidget_show(winwid); } @@ -348,7 +341,6 @@ void init_index_mode(void) if (!opt.display) gib_imlib_free_image_and_decache(im_main); - free(s); return; } diff --git a/src/multiwindow.c b/src/multiwindow.c index 13cff90..abbf6c9 100644 --- a/src/multiwindow.c +++ b/src/multiwindow.c @@ -34,25 +34,14 @@ void init_multiwindow_mode(void) { winwidget w = NULL; gib_list *l; - feh_file *file = NULL; + + if (!opt.title) + opt.title = PACKAGE " - %f"; mode = "multiwindow"; for (l = filelist; l; l = l->next) { - char *s = NULL; - int len = 0; - file = FEH_FILE(l->data); - current_file = l; - - if (!opt.title) { - len = strlen(PACKAGE " - ") + strlen(file->filename) + 1; - s = emalloc(len); - snprintf(s, len, PACKAGE " - %s", file->filename); - } else { - s = estrdup(feh_printf(opt.title, file, w)); - } - - if ((w = winwidget_create_from_file(l, s, WIN_TYPE_SINGLE)) != NULL) { + if ((w = winwidget_create_from_file(l, WIN_TYPE_SINGLE)) != NULL) { winwidget_show(w); if (opt.reload > 0) feh_add_unique_timer(cb_reload_timer, w, opt.reload); @@ -62,7 +51,6 @@ void init_multiwindow_mode(void) D(("EEEK. Couldn't load image in multiwindow mode. " "I 'm not sure if this is a problem\n")); } - free(s); } return; diff --git a/src/slideshow.c b/src/slideshow.c index 80fa918..c6d82a6 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -48,6 +48,9 @@ void init_slideshow_mode(void) 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) { @@ -55,7 +58,7 @@ void init_slideshow_mode(void) last = NULL; } current_file = l; - if ((w = winwidget_create_from_file(l, NULL, WIN_TYPE_SLIDESHOW)) != NULL) { + if ((w = winwidget_create_from_file(l, WIN_TYPE_SLIDESHOW)) != NULL) { success = 1; winwidget_show(w); if (opt.slideshow_delay > 0.0) @@ -124,13 +127,6 @@ void cb_reload_timer(void *data) 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); feh_add_unique_timer(cb_reload_timer, w, opt.reload); return; @@ -138,7 +134,7 @@ void cb_reload_timer(void *data) void feh_reload_image(winwidget w, int resize, int force_new) { - char *title, *new_title; + char *new_title; int len; Imlib_Image tmp; int old_w, old_h; @@ -167,8 +163,8 @@ void feh_reload_image(winwidget w, int resize, int force_new) len = strlen(w->name) + sizeof("Reloading: ") + 1; new_title = emalloc(len); snprintf(new_title, len, "Reloading: %s", w->name); - title = estrdup(w->name); winwidget_rename(w, new_title); + free(new_title); old_w = gib_imlib_image_get_width(w->im); old_h = gib_imlib_image_get_height(w->im); @@ -189,9 +185,6 @@ void feh_reload_image(winwidget w, int resize, int force_new) im_weprintf(w, "Couldn't reload image. Is it still there?"); winwidget_render_image(w, 0, 0); } - winwidget_rename(w, title); - free(title); - free(new_title); return; } @@ -231,10 +224,6 @@ void feh_reload_image(winwidget w, int resize, int force_new) winwidget_render_image(w, resize, 0); } - winwidget_rename(w, title); - free(title); - free(new_title); - return; } @@ -247,7 +236,6 @@ void slideshow_change_image(winwidget winwid, int change, int render) * encounter invalid images. */ int our_filelist_len = filelist_len; - char *s; unsigned char tmode =0; int tim_x =0; @@ -396,11 +384,6 @@ void slideshow_change_image(winwidget winwid, int change, int render) winwidget_render_image(winwid, 1, 0); } } - - s = slideshow_create_name(FEH_FILE(current_file->data), winwid); - winwidget_rename(winwid, s); - free(s); - break; } else last = current_file; @@ -427,23 +410,6 @@ void slideshow_pause_toggle(winwidget w) winwidget_rename(w, NULL); } -char *slideshow_create_name(feh_file * file, winwidget winwid) -{ - char *s = NULL; - int len = 0; - - if (!opt.title) { - len = strlen(PACKAGE " [slideshow mode] - ") + strlen(file->filename) + 1; - s = emalloc(len); - snprintf(s, len, PACKAGE " [%d of %d] - %s", - gib_list_num(filelist, current_file) + 1, gib_list_length(filelist), file->filename); - } else { - s = estrdup(feh_printf(opt.title, file, winwid)); - } - - return(s); -} - void feh_action_run(feh_file * file, char *action, winwidget winwid) { if (action) { @@ -480,6 +446,7 @@ char *feh_printf(char *str, feh_file * file, winwidget winwid) ret[0] = '\0'; filelist_tmppath = NULL; + gib_list *f; for (c = str; *c != '\0'; c++) { if ((*c == '%') && (*(c+1) != '\0')) { @@ -564,9 +531,8 @@ char *feh_printf(char *str, feh_file * file, winwidget winwid) } break; case 'u': - snprintf(buf, sizeof(buf), "%d", - current_file != NULL ? gib_list_num(filelist, current_file) - + 1 : 0); + f = current_file ? current_file : gib_list_find_by_data(filelist, file); + snprintf(buf, sizeof(buf), "%d", f ? gib_list_num(filelist, f) + 1 : 0); strncat(ret, buf, sizeof(ret) - strlen(ret) - 1); break; case 'v': @@ -620,7 +586,6 @@ char *feh_printf(char *str, feh_file * file, winwidget winwid) void feh_filelist_image_remove(winwidget winwid, char do_delete) { if (winwid->type == WIN_TYPE_SLIDESHOW) { - char *s; gib_list *doomed; doomed = current_file; @@ -647,9 +612,6 @@ void feh_filelist_image_remove(winwidget winwid, char do_delete) winwidget_destroy(winwid); return; } - s = slideshow_create_name(FEH_FILE(winwid->file->data), winwid); - winwidget_rename(winwid, s); - free(s); winwidget_render_image(winwid, 1, 0); } else if ((winwid->type == WIN_TYPE_SINGLE) || (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)) { diff --git a/src/thumbnail.c b/src/thumbnail.c index edf0f4f..003c7b4 100644 --- a/src/thumbnail.c +++ b/src/thumbnail.c @@ -71,7 +71,6 @@ void init_thumbnail_mode(void) gib_list *l, *last = NULL; int lineno; int index_image_width, index_image_height; - char *s; unsigned int thumb_counter = 0; gib_list *line, *lines; @@ -92,6 +91,9 @@ void init_thumbnail_mode(void) td.vertical = 0; td.max_column_w = 0; + if (!opt.thumb_title) + opt.thumb_title = "%n"; + mode = "thumbnail"; if (opt.font) @@ -168,15 +170,9 @@ void init_thumbnail_mode(void) td.h + title_area_h, 0, 0, 0, 255); } - /* Create title now */ - - if (!opt.title) - s = estrdup(PACKAGE " [thumbnail mode]"); - else - s = estrdup(feh_printf(opt.title, NULL, NULL)); - if (opt.display) { - winwid = winwidget_create_from_image(td.im_main, s, WIN_TYPE_THUMBNAIL); + winwid = winwidget_create_from_image(td.im_main, WIN_TYPE_THUMBNAIL); + winwidget_rename(winwid, PACKAGE " [thumbnail mode]"); winwidget_show(winwid); } @@ -415,8 +411,6 @@ void init_thumbnail_mode(void) } } - - free(s); return; } @@ -772,24 +766,17 @@ int feh_thumbnail_get_generated(Imlib_Image * image, feh_file * file, void feh_thumbnail_show_fullsize(feh_file *thumbfile) { winwidget thumbwin = NULL; - char *s; - if (!opt.thumb_title) - s = thumbfile->name; - else - s = feh_printf(opt.thumb_title, thumbfile, NULL); - thumbwin = winwidget_get_first_window_of_type(WIN_TYPE_THUMBNAIL_VIEWER); if (!thumbwin) { thumbwin = winwidget_create_from_file( gib_list_add_front(NULL, thumbfile), - s, WIN_TYPE_THUMBNAIL_VIEWER); + WIN_TYPE_THUMBNAIL_VIEWER); if (thumbwin) winwidget_show(thumbwin); } else if (FEH_FILE(thumbwin->file->data) != thumbfile) { free(thumbwin->file); thumbwin->file = gib_list_add_front(NULL, thumbfile); - winwidget_rename(thumbwin, s); feh_reload_image(thumbwin, 1, 1); } } @@ -925,16 +912,3 @@ int feh_thumbnail_setup_thumbnail_dir(void) return status; } - -char *thumbnail_create_name(feh_file * file, winwidget winwid) -{ - char *s = NULL; - - if (!opt.thumb_title) { - s = estrdup(file->filename); - } else { - s = estrdup(feh_printf(opt.thumb_title, file, winwid)); - } - - return(s); -} diff --git a/src/winwidget.c b/src/winwidget.c index d636a85..3311383 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -81,7 +81,7 @@ static winwidget winwidget_allocate(void) return(ret); } -winwidget winwidget_create_from_image(Imlib_Image im, char *name, char type) +winwidget winwidget_create_from_image(Imlib_Image im, char type) { winwidget ret = NULL; @@ -95,11 +95,6 @@ winwidget winwidget_create_from_image(Imlib_Image im, char *name, char type) ret->w = ret->im_w = gib_imlib_image_get_width(ret->im); ret->h = ret->im_h = gib_imlib_image_get_height(ret->im); - if (name) - ret->name = estrdup(name); - else - ret->name = estrdup(PACKAGE); - if (opt.full_screen && (type != WIN_TYPE_THUMBNAIL)) ret->full_screen = True; winwidget_create_window(ret, ret->w, ret->h); @@ -108,7 +103,7 @@ winwidget winwidget_create_from_image(Imlib_Image im, char *name, char type) return(ret); } -winwidget winwidget_create_from_file(gib_list * list, char *name, char type) +winwidget winwidget_create_from_file(gib_list * list, char type) { winwidget ret = NULL; feh_file *file = FEH_FILE(list->data); @@ -119,10 +114,6 @@ winwidget winwidget_create_from_file(gib_list * list, char *name, char type) ret = winwidget_allocate(); ret->file = list; ret->type = type; - if (name) - ret->name = estrdup(name); - else - ret->name = estrdup(file->filename); if (winwidget_loadimage(ret, file) == 0) { winwidget_destroy(ret); @@ -632,16 +623,12 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) feh_draw_info(winwid); if (winwid->errstr) feh_draw_errstr(winwid); - if (opt.title && (winwid->type != WIN_TYPE_THUMBNAIL_VIEWER) && - (winwid->file != NULL)) { - char *s = slideshow_create_name(FEH_FILE(winwid->file->data), winwid); - winwidget_rename(winwid, s); - free(s); - } else if (opt.thumb_title && (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) && - (winwid->file != NULL)) { - char *s = thumbnail_create_name(FEH_FILE(winwid->file->data), winwid); - winwidget_rename(winwid, s); - free(s); + if (winwid->file != NULL) { + if (opt.title && winwid->type != WIN_TYPE_THUMBNAIL_VIEWER) { + winwidget_rename(winwid, feh_printf(opt.title, FEH_FILE(winwid->file->data), winwid)); + } else if (opt.thumb_title && winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) { + winwidget_rename(winwid, feh_printf(opt.thumb_title, FEH_FILE(winwid->file->data), winwid)); + } } } else if ((opt.mode == MODE_ZOOM) && !antialias) feh_draw_zoom(winwid); diff --git a/src/winwidget.h b/src/winwidget.h index 6a794e7..dd8489a 100644 --- a/src/winwidget.h +++ b/src/winwidget.h @@ -141,8 +141,8 @@ void winwidget_get_geometry(winwidget winwid, int *rect); int winwidget_get_width(winwidget winwid); int winwidget_get_height(winwidget winwid); winwidget winwidget_get_from_window(Window win); -winwidget winwidget_create_from_file(gib_list * filename, char *name, char type); -winwidget winwidget_create_from_image(Imlib_Image im, char *name, char type); +winwidget winwidget_create_from_file(gib_list * filename, char type); +winwidget winwidget_create_from_image(Imlib_Image im, char type); void winwidget_rename(winwidget winwid, char *newname); void winwidget_destroy(winwidget winwid); void winwidget_create_window(winwidget ret, int w, int h); -- cgit v1.2.3 From fe8ce5419da5f08e0923e759753b75edc53906b3 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Mon, 29 Jan 2018 21:01:03 +0100 Subject: Include system headers before local ones to fix type conflict on OpenBSD --- src/feh_png.c | 4 ++-- src/feh_png.h | 4 ++-- src/gib_hash.c | 2 +- src/options.c | 3 ++- src/wallpaper.c | 6 ++++-- 5 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/feh_png.c b/src/feh_png.c index d27df01..d0c1c8a 100644 --- a/src/feh_png.c +++ b/src/feh_png.c @@ -23,13 +23,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "feh_png.h" - #include #include #include +#include "feh_png.h" + #define FEH_PNG_COMPRESSION 3 #define FEH_PNG_NUM_COMMENTS 4 diff --git a/src/feh_png.h b/src/feh_png.h index ac3375f..035d36a 100644 --- a/src/feh_png.h +++ b/src/feh_png.h @@ -26,11 +26,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef FEH_PNG_H #define FEH_PNG_H -#include "feh.h" - #include #include +#include "feh.h" + gib_hash *feh_png_read_comments(char *file); int feh_png_write_png_fd(Imlib_Image image, int fd, ...); diff --git a/src/gib_hash.c b/src/gib_hash.c index 15bbf4a..0d6a226 100644 --- a/src/gib_hash.c +++ b/src/gib_hash.c @@ -22,11 +22,11 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include #include "gib_hash.h" #include "utils.h" #include "debug.h" -#include gib_hash_node *gib_hash_node_new(char *key, void *data) { diff --git a/src/options.c b/src/options.c index c874832..837d7a8 100644 --- a/src/options.c +++ b/src/options.c @@ -24,10 +24,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include + #include "feh.h" #include "filelist.h" #include "options.h" -#include static void check_options(void); static void feh_getopt_theme(int argc, char **argv); diff --git a/src/wallpaper.c b/src/wallpaper.c index c9a3a05..34694ae 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -24,12 +24,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include +#include + #include "feh.h" #include "filelist.h" #include "options.h" #include "wallpaper.h" -#include -#include + Window ipc_win = None; Window my_ipc_win = None; Atom ipc_atom = None; -- cgit v1.2.3 From 26435c1a89d8fb2a30564165da20b41917e72389 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Mon, 29 Jan 2018 21:17:08 +0100 Subject: Makefile: Also honor CFLAGS when building deps.mk --- src/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Makefile b/src/Makefile index 2f6185a..8a9f97e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -51,9 +51,9 @@ include deps.mk fehrc.inc: fehrc.raw help.inc: help.raw - +# CFLAGS might contain include paths needed to resolve includes in headers deps.mk: ${TARGETS} ${I_DSTS} - ${CC} ${CPPFLAGS} -MM ${TARGETS} > $@ + ${CC} ${CFLAGS} -MM ${TARGETS} > $@ clean: rm -f feh *.o *.inc -- cgit v1.2.3 From 078beeeaae30503620d0c9266bb8fd9ce3e08f1f Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Fri, 9 Feb 2018 21:10:09 +0100 Subject: parse_options_from_string: only leave quote if start and end character match Closes #381 --- src/options.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/options.c b/src/options.c index 837d7a8..bf5c67c 100644 --- a/src/options.c +++ b/src/options.c @@ -214,7 +214,7 @@ static void feh_parse_options_from_string(char *opts) char *s; char *t; char last = 0; - int inquote = 0; + char inquote = 0; int i = 0; /* So we don't reinvent the wheel (not again, anyway), we use the @@ -229,7 +229,7 @@ static void feh_parse_options_from_string(char *opts) eprintf(PACKAGE " does not support more than 64 words per " "theme definition.\n Please shorten your lines."); - if ((*t == ' ') && !(inquote)) { + if ((*t == ' ') && !inquote) { *t = '\0'; num++; @@ -240,8 +240,10 @@ static void feh_parse_options_from_string(char *opts) list[num - 1] = feh_string_normalize(s); break; - } else if (((*t == '\"') || (*t == '\'')) && last != '\\') - inquote = !(inquote); + } else if ((*t == inquote) && (last != '\\')) { + inquote = 0; + } else if (((*t == '\"') || (*t == '\'')) && (last != '\\') && !inquote) + inquote = *t; last = *t; } -- cgit v1.2.3 From 5e75b5ef3e7d0270913c04645398bc3596c2a90a Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 14 Feb 2018 22:33:38 +0100 Subject: Only check image dimensions on the fly in multiwindow and slideshow mode This introduces a new feh_should_ignore_image function which is called at appropriate places in those modes to skip images which are loadable but undesired. --- src/feh.h | 1 + src/filelist.c | 12 +++++++++++- src/imlib.c | 12 ++++++++++++ src/options.c | 2 ++ src/options.h | 1 + src/slideshow.c | 14 ++++++-------- src/winwidget.c | 2 +- 7 files changed, 34 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/feh.h b/src/feh.h index bfd71db..60baade 100644 --- a/src/feh.h +++ b/src/feh.h @@ -133,6 +133,7 @@ void init_list_mode(void); void init_loadables_mode(void); void init_unloadables_mode(void); void feh_clean_exit(void); +int feh_should_ignore_image(Imlib_Image * im); int feh_load_image(Imlib_Image * im, feh_file * file); void show_mini_usage(void); void slideshow_change_image(winwidget winwid, int change, int render); diff --git a/src/filelist.c b/src/filelist.c index 0066efd..9a4af27 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -464,7 +464,17 @@ int feh_cmp_format(void *file1, void *file2) void feh_prepare_filelist(void) { - if (opt.list || opt.preload || opt.customlist || (opt.sort > SORT_MTIME)) { + /* + * list and customlist mode as well as the somewhat more fancy sort modes + * need access to file infos. Preloading them is also useful for + * list/customlist as --min-dimension/--max-dimension may filter images + * which should not be processed. + * Finally, if --min-dimension/--max-dimension (-> opt.filter_by_dimensions) + * is set and we're in thumbnail mode, we need to filter images first so + * we can create a properly sized thumbnail list. + */ + if (opt.list || opt.preload || opt.customlist || (opt.sort > SORT_MTIME) + || (opt.filter_by_dimensions && (opt.index || opt.collage || opt.thumbs || opt.bgmode))) { /* For these sort options, we have to preload images */ filelist = feh_file_info_preload(filelist); if (!gib_list_length(filelist)) diff --git a/src/imlib.c b/src/imlib.c index 6de6bdb..d9c5cd0 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -139,6 +139,18 @@ void init_x_and_imlib(void) return; } +int feh_should_ignore_image(Imlib_Image * im) +{ + if (opt.filter_by_dimensions) { + unsigned int w = gib_imlib_image_get_width(im); + unsigned int h = gib_imlib_image_get_height(im); + if (w < opt.min_width || w > opt.max_width || h < opt.min_height || h > opt.max_height) { + return 1; + } + } + return 0; +} + int feh_load_image_char(Imlib_Image * im, char *filename) { feh_file *file; diff --git a/src/options.c b/src/options.c index bf5c67c..76d70c5 100644 --- a/src/options.c +++ b/src/options.c @@ -433,6 +433,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) opt.debug = 1; break; case '<': + opt.filter_by_dimensions = 1; XParseGeometry(optarg, &discard, &discard, &opt.max_width, &opt.max_height); if (opt.max_width == 0) opt.max_width = UINT_MAX; @@ -440,6 +441,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) opt.max_height = UINT_MAX; break; case '>': + opt.filter_by_dimensions = 1; XParseGeometry(optarg, &discard, &discard, &opt.min_width, &opt.min_height); break; case '.': diff --git a/src/options.h b/src/options.h index c6959c8..9bf2763 100644 --- a/src/options.h +++ b/src/options.h @@ -75,6 +75,7 @@ struct __fehoptions { unsigned char no_fehbg; unsigned char keep_zoom_vp; unsigned char insecure_ssl; + unsigned char filter_by_dimensions; char *output_file; char *output_dir; diff --git a/src/slideshow.c b/src/slideshow.c index 6ab56fa..d56c1b6 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -361,17 +361,15 @@ void slideshow_change_image(winwidget winwid, int change, int render) } if (winwidget_loadimage(winwid, FEH_FILE(current_file->data))) { - unsigned int w = gib_imlib_image_get_width(winwid->im); - unsigned int h = gib_imlib_image_get_height(winwid->im); - if (opt.min_width || opt.min_height || (opt.max_width != UINT_MAX) || (opt.max_height != UINT_MAX)) { - if (w < opt.min_width || w > opt.max_width || h < opt.min_height || h > opt.max_height) { - last = current_file; - continue; - } + int w = gib_imlib_image_get_width(winwid->im); + int h = gib_imlib_image_get_height(winwid->im); + if (feh_should_ignore_image(winwid->im)) { + last = current_file; + continue; } winwid->mode = MODE_NORMAL; winwid->file = current_file; - if ((winwid->im_w != (int)w) || (winwid->im_h != (int)h)) + if ((winwid->im_w != w) || (winwid->im_h != h)) winwid->had_resize = 1; winwidget_reset_image(winwid); winwid->im_w = w; diff --git a/src/winwidget.c b/src/winwidget.c index 3311383..9600465 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -115,7 +115,7 @@ winwidget winwidget_create_from_file(gib_list * list, char type) ret->file = list; ret->type = type; - if (winwidget_loadimage(ret, file) == 0) { + if ((winwidget_loadimage(ret, file) == 0) || feh_should_ignore_image(ret->im)) { winwidget_destroy(ret); return(NULL); } -- cgit v1.2.3 From 0db40a597c920eb0c22305d71c8e51ef46016b1e Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sun, 25 Feb 2018 09:31:05 +0100 Subject: Fix segfault when using %m format specifier in slideshow mode Closes: #382, #384 --- src/slideshow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/slideshow.c b/src/slideshow.c index d56c1b6..1615608 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -49,7 +49,7 @@ void init_slideshow_mode(void) opt.start_list_at); if (!opt.title) - opt.title = PACKAGE " [%u of %l] - %f", + opt.title = PACKAGE " [%u of %l] - %f"; mode = "slideshow"; for (; l; l = l->next) { -- cgit v1.2.3 From 8eaa39234a54fcdd3c9050a01790b152598af80d Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Tue, 27 Feb 2018 19:35:59 +0100 Subject: Handle transparency when setting background images --- src/wallpaper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/wallpaper.c b/src/wallpaper.c index cfefb8f..758a81a 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -91,7 +91,7 @@ static void feh_wm_set_bg_scaled(Pixmap pmap, Imlib_Image im, int use_filelist, feh_wm_load_next(&im); gib_imlib_render_image_on_drawable_at_size(pmap, im, x, y, w, h, - 1, 0, !opt.force_aliasing); + 1, 1, !opt.force_aliasing); if (use_filelist) gib_imlib_free_image_and_decache(im); @@ -132,7 +132,7 @@ static void feh_wm_set_bg_centered(Pixmap pmap, Imlib_Image im, int use_filelist y + ((offset_y > 0) ? offset_y : 0), w, h, - 1, 0, 0); + 1, 1, 0); if (use_filelist) gib_imlib_free_image_and_decache(im); @@ -212,7 +212,7 @@ static void feh_wm_set_bg_maxed(Pixmap pmap, Imlib_Image im, int use_filelist, gib_imlib_render_image_on_drawable_at_size(pmap, im, render_x, render_y, render_w, render_h, - 1, 0, !opt.force_aliasing); + 1, 1, !opt.force_aliasing); if (use_filelist) gib_imlib_free_image_and_decache(im); @@ -420,7 +420,7 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, w = gib_imlib_image_get_width(im); h = gib_imlib_image_get_height(im); pmap_d1 = XCreatePixmap(disp, root, w, h, depth); - gib_imlib_render_image_on_drawable(pmap_d1, im, 0, 0, 1, 0, 0); + gib_imlib_render_image_on_drawable(pmap_d1, im, 0, 0, 1, 1, 0); } if (!opt.no_fehbg) { -- cgit v1.2.3 From 4567042b5145b097c962499f26511aa5106f0e60 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 28 Feb 2018 17:53:51 +0100 Subject: Add Makefile flag to disable version sorting on C libraries without strverscmp --- README.md | 1 + config.mk | 10 +++++++++- man/Makefile | 1 + man/feh.pre | 3 ++- src/feh.h | 7 +++++++ src/filelist.c | 29 +++++++++++++++-------------- 6 files changed, 35 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/README.md b/README.md index 328897a..7848158 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ Available flags are: | exif | 0 | Builtin EXIF tag display support | | help | 0 | include help text (refers to the manpage otherwise) | | stat64 | 0 | Support CIFS shares from 64bit hosts on 32bit machines | +| verscmp | 1 | Support naturing sorting (`--version-sort`). Requires a GNU-compatible libc exposing `strverscmp` | | xinerama | 1 | Support Xinerama/XRandR multiscreen setups | So, by default **libcurl** and **Xinerama** are enabled, the rest is disabled. diff --git a/config.mk b/config.mk index 8769b1d..226c612 100644 --- a/config.mk +++ b/config.mk @@ -5,9 +5,10 @@ app ?= 0 cam ?= 0 curl ?= 1 debug ?= 0 +exif ?= 0 help ?= 0 +verscmp ?= 1 xinerama ?= 1 -exif ?= 0 # Prefix for all installed files PREFIX ?= /usr/local @@ -63,6 +64,13 @@ ifeq (${stat64},1) CFLAGS += -D_FILE_OFFSET_BITS=64 endif +ifeq (${verscmp},1) + CFLAGS += -DHAVE_VERSCMP + MAN_VERSCMP = enabled +else + MAN_VERSCMP = disabled +endif + ifeq (${xinerama},1) CFLAGS += -DHAVE_LIBXINERAMA LDLIBS += -lXinerama diff --git a/man/Makefile b/man/Makefile index 65f2bc2..9209de1 100644 --- a/man/Makefile +++ b/man/Makefile @@ -12,6 +12,7 @@ all: ${TARGETS} -e 's/\$$MAN_CURL\$$/${MAN_CURL}/' \ -e 's/\$$MAN_DEBUG\$$/${MAN_DEBUG}/' \ -e 's/\$$MAN_EXIF\$$/${MAN_EXIF}/' \ + -e 's/\$$MAN_VERSCMP\$$/${MAN_VERSCMP}/' \ -e 's/\$$MAN_XINERAMA\$$/${MAN_XINERAMA}/' \ < ${@:.1=.pre} > $@ diff --git a/man/feh.pre b/man/feh.pre index d332774..640ae3f 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -24,7 +24,8 @@ $VERSION$ . .Pp . -Compile-time switches: libcurl support $MAN_CURL$, Xinerama support +Compile-time switches: libcurl support $MAN_CURL$, natural sorting support +$MAN_VERSCMP$, Xinerama support $MAN_XINERAMA$, builtin EXIF support $MAN_EXIF$$MAN_DEBUG$ . . diff --git a/src/feh.h b/src/feh.h index 4e7a3ff..3e0cdda 100644 --- a/src/feh.h +++ b/src/feh.h @@ -27,7 +27,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef FEH_H #define FEH_H +/* + * strverscmp(3) is a GNU extension. In most supporting C libraries it + * requires _GNU_SOURCE to be defined. + */ +#ifdef HAVE_VERSCMP #define _GNU_SOURCE +#endif + #include #include #include diff --git a/src/filelist.c b/src/filelist.c index 159491a..453f795 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -397,20 +397,26 @@ void feh_file_dirname(char *dst, feh_file * f, int maxlen) dst[n] = '\0'; } -int feh_cmp_filename(void *file1, void *file2) +#ifdef HAVE_VERSCMP +inline int strcmp_or_strverscmp(const char *s1, const char *s2) { if (!opt.version_sort) - return(strcmp(FEH_FILE(file1)->filename, FEH_FILE(file2)->filename)); + return(strcmp(s1, s2)); else - return(strverscmp(FEH_FILE(file1)->filename, FEH_FILE(file2)->filename)); + return(strverscmp(s1, s2)); +} +#else +#define strcmp_or_strverscmp strcmp +#endif + +int feh_cmp_filename(void *file1, void *file2) +{ + return(strcmp_or_strverscmp(FEH_FILE(file1)->filename, FEH_FILE(file2)->filename)); } int feh_cmp_name(void *file1, void *file2) { - if (!opt.version_sort) - return(strcmp(FEH_FILE(file1)->name, FEH_FILE(file2)->name)); - else - return(strverscmp(FEH_FILE(file1)->name, FEH_FILE(file2)->name)); + return(strcmp_or_strverscmp(FEH_FILE(file1)->name, FEH_FILE(file2)->name)); } int feh_cmp_dirname(void *file1, void *file2) @@ -419,13 +425,8 @@ int feh_cmp_dirname(void *file1, void *file2) int cmp; feh_file_dirname(dir1, FEH_FILE(file1), PATH_MAX); feh_file_dirname(dir2, FEH_FILE(file2), PATH_MAX); - if (!opt.version_sort) { - if ((cmp = strcmp(dir1, dir2)) != 0) - return(cmp); - } else { - if ((cmp = strverscmp(dir1, dir2)) != 0) - return(cmp); - } + if ((cmp = strcmp_or_strverscmp(dir1, dir2)) != 0) + return(cmp); return(feh_cmp_name(file1, file2)); } -- cgit v1.2.3 From c2e0b7239522dc417b87f45cd133fb8f046dedfa Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 28 Feb 2018 19:44:21 +0100 Subject: Respect --geometry in --bg-fill (closes #209) --- man/feh.pre | 10 +++++----- src/wallpaper.c | 27 ++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/man/feh.pre b/man/feh.pre index 5290f79..46de5d1 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -919,13 +919,13 @@ instead. . .Pp . -For the -.Cm --bg-center +For +.Cm --bg-center , --bg-fill , and -.Cm --bg-max -options, you can use the +.Cm --bg-max , +you can use .Cm --geometry -option to specify an offset from one side of the screen instead of +to specify an offset from one side of the screen instead of centering the image. Positive values will offset from the left/top side, negative values from the bottom/right. +0 and -0 are both valid and distinct values. diff --git a/src/wallpaper.c b/src/wallpaper.c index 758a81a..2d3d3bc 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -160,11 +160,36 @@ static void feh_wm_set_bg_filled(Pixmap pmap, Imlib_Image im, int use_filelist, render_x = ( cut_x ? ((img_w - render_w) >> 1) : 0); render_y = ( !cut_x ? ((img_h - render_h) >> 1) : 0); + if ((opt.geom_flags & XValue) && cut_x) { + if (opt.geom_flags & XNegative) { + render_x = img_w - render_w + opt.geom_x; + } else { + render_x = opt.geom_x; + } + if (render_x < 0) { + render_x = 0; + } else if (render_x + render_w > img_w) { + render_x = img_w - render_w; + } + } + else if ((opt.geom_flags & YValue) && !cut_x) { + if (opt.geom_flags & YNegative) { + render_y = img_h - render_h + opt.geom_y; + } else { + render_y = opt.geom_y; + } + if (render_y < 0) { + render_y = 0; + } else if (render_y + render_h > img_h) { + render_y = img_h - render_h; + } + } + gib_imlib_render_image_part_on_drawable_at_size(pmap, im, render_x, render_y, render_w, render_h, x, y, w, h, - 1, 0, !opt.force_aliasing); + 1, 1, !opt.force_aliasing); if (use_filelist) gib_imlib_free_image_and_decache(im); -- cgit v1.2.3 From d03fc61a268048e1bcef04fb00883c6cd339027b Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 28 Feb 2018 20:06:33 +0100 Subject: Add toggle_auto_zoom key binding, defaulting to Z Closes #218 --- man/feh.pre | 4 ++++ src/keyevents.c | 5 +++++ src/options.h | 1 + 3 files changed, 10 insertions(+) (limited to 'src') diff --git a/man/feh.pre b/man/feh.pre index 6c619cd..d90c880 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -1376,6 +1376,10 @@ Close current window . Jump to a random position in the current filelist . +.It Z Bq toggle_auto_zoom +. +Toggle auto-zoom. +. .It \&[, \&] Bq prev_dir, next_dir . Jump to the first image of the previous or next sequence of images sharing diff --git a/src/keyevents.c b/src/keyevents.c index f082a78..793767b 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -185,6 +185,7 @@ void init_keyevents(void) { feh_set_kb("render" , 0, XK_KP_Begin , 0, XK_R , 0, 0); feh_set_kb("toggle_actions" , 0, XK_a, 0, 0, 0, 0); feh_set_kb("toggle_aliasing" , 0, XK_A, 0, 0, 0, 0); + feh_set_kb("toggle_auto_zoom" , 0, XK_Z, 0, 0, 0, 0); #ifdef HAVE_LIBEXIF feh_set_kb("toggle_exif" , 0, XK_e, 0, 0, 0, 0); #endif @@ -637,6 +638,10 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy winwid->force_aliasing = !winwid->force_aliasing; winwidget_render_image(winwid, 0, 0); } + else if (feh_is_kp(EVENT_toggle_auto_zoom, state, keysym, button)) { + opt.zoom_mode = (opt.zoom_mode == 0 ? ZOOM_MODE_MAX : 0); + winwidget_rerender_all(1); + } else if (feh_is_kp(EVENT_toggle_filenames, state, keysym, button)) { opt.draw_filename = !opt.draw_filename; winwidget_rerender_all(0); diff --git a/src/options.h b/src/options.h index c6b4e0e..d4de3c5 100644 --- a/src/options.h +++ b/src/options.h @@ -189,6 +189,7 @@ enum key_action { EVENT_render, EVENT_toggle_actions, EVENT_toggle_aliasing, + EVENT_toggle_auto_zoom, #ifdef HAVE_LIBEXIF EVENT_toggle_exif, #endif -- cgit v1.2.3 From 05e745a519248c1907340c7f5b0b7bc65f0409eb Mon Sep 17 00:00:00 2001 From: ulteq Date: Fri, 19 Jan 2018 12:22:09 +0100 Subject: Utilize dcraw to preview RAW files Uses the camera-generated thumbnail to display RAW images that could otherwise not be loaded. --- src/imlib.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- src/options.c | 5 +++ src/options.h | 1 + 3 files changed, 108 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/imlib.c b/src/imlib.c index d9c5cd0..b6041fc 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -61,7 +61,9 @@ int num_xinerama_screens; int childpid = 0; +static int feh_file_is_raw(char *filename); static char *feh_http_load_image(char *url); +static char *feh_dcraw_load_image(char *filename); static char *feh_magick_load_image(char *filename); #ifdef HAVE_LIBXINERAMA @@ -216,8 +218,7 @@ 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 = IMLIB_LOAD_ERROR_NONE; - enum { SRC_IMLIB, SRC_HTTP, SRC_MAGICK } image_source = - SRC_IMLIB; + enum { SRC_IMLIB, SRC_HTTP, SRC_MAGICK, SRC_DCRAW } image_source = SRC_IMLIB; char *tmpname = NULL; char *real_filename = NULL; @@ -232,16 +233,23 @@ int feh_load_image(Imlib_Image * im, feh_file * file) if ((tmpname = feh_http_load_image(file->filename)) == NULL) err = IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST; } + else if (opt.dcraw_timeout >= 0 && feh_file_is_raw(file->filename)) { + image_source = SRC_DCRAW; + tmpname = feh_dcraw_load_image(file->filename); + if (!tmpname) + err = IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT; + } else *im = imlib_load_image_with_error_return(file->filename, &err); - if ((err == IMLIB_LOAD_ERROR_UNKNOWN) - || (err == IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT)) { + if (opt.magick_timeout >= 0 && ( + (err == IMLIB_LOAD_ERROR_UNKNOWN) || + (err == IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT))) { image_source = SRC_MAGICK; tmpname = feh_magick_load_image(file->filename); } - if ((image_source != SRC_IMLIB) && tmpname) { + if (tmpname) { *im = imlib_load_image_with_error_return(tmpname, &err); if (!err && im) { real_filename = file->filename; @@ -301,6 +309,95 @@ int feh_load_image(Imlib_Image * im, feh_file * file) return(1); } +static int feh_file_is_raw(char *filename) +{ + childpid = fork(); + if (childpid == -1) { + perror("fork"); + return 0; + } + + if (childpid == 0) { + if (opt.quiet) { + int devnull = open("/dev/null", O_WRONLY); + dup2(devnull, 1); + dup2(devnull, 2); + } + execlp("dcraw", "dcraw", "-i", filename, NULL); + _exit(1); + } else { + int status; + do { + waitpid(childpid, &status, WUNTRACED); + if (WIFEXITED(status)) { + return !WEXITSTATUS(status); + } + } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + } + + return 0; +} + +static char *feh_dcraw_load_image(char *filename) +{ + char *basename; + char *tmpname; + char *sfn; + int fd = -1; + + basename = strrchr(filename, '/'); + + if (basename == NULL) + basename = filename; + else + basename++; + + tmpname = feh_unique_filename("/tmp/", basename); + + if (strlen(tmpname) > (NAME_MAX-6)) + tmpname[NAME_MAX-7] = '\0'; + + sfn = estrjoin("_", tmpname, "XXXXXX", NULL); + free(tmpname); + + fd = mkstemp(sfn); + + if (fd == -1) { + free(sfn); + return NULL; + } + + childpid = fork(); + if (childpid == -1) { + weprintf("%s: Can't load with dcraw. Fork failed:", filename); + unlink(sfn); + free(sfn); + close(fd); + return NULL; + } else if (childpid == 0) { + + close(1); + dup(fd); + close(fd); + + alarm(opt.dcraw_timeout); + execlp("dcraw", "dcraw", "-c", "-e", filename, NULL); + _exit(1); + } + + int status; + waitpid(-1, &status, 0); + if (WIFSIGNALED(status)) { + unlink(sfn); + free(sfn); + sfn = NULL; + if (!opt.quiet) + weprintf("%s - Conversion took too long, skipping", filename); + } + + return sfn; +} + static char *feh_magick_load_image(char *filename) { char *argv_fn; @@ -310,9 +407,6 @@ static char *feh_magick_load_image(char *filename) int fd = -1, devnull = -1; int status; - if (opt.magick_timeout < 0) - return NULL; - basename = strrchr(filename, '/'); if (basename == NULL) diff --git a/src/options.c b/src/options.c index 3d11482..29ce836 100644 --- a/src/options.c +++ b/src/options.c @@ -55,6 +55,7 @@ void init_parse_options(int argc, char **argv) opt.display = 1; opt.aspect = 1; opt.slideshow_delay = 0.0; + opt.dcraw_timeout = -1; opt.magick_timeout = -1; opt.thumb_w = 60; opt.thumb_h = 60; @@ -415,6 +416,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"insecure" , 0, 0, 240}, {"no-recursive" , 0, 0, 241}, {"cache-size" , 1, 0, 243}, + {"dcraw-timeout" , 1, 0, 245}, {"version-sort" , 0, 0, 246}, {0, 0, 0, 0} }; @@ -781,6 +783,9 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) if (opt.cache_size > 2048) opt.cache_size = 2048; break; + case 245: + opt.dcraw_timeout = atoi(optarg); + break; case 246: opt.version_sort = 1; break; diff --git a/src/options.h b/src/options.h index d4de3c5..88121e6 100644 --- a/src/options.h +++ b/src/options.h @@ -129,6 +129,7 @@ struct __fehoptions { double slideshow_delay; + signed short dcraw_timeout; signed short magick_timeout; Imlib_Font menu_fn; -- cgit v1.2.3 From 204dbfc81febe94ae86a985c653ef4875bb93853 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 7 Mar 2018 15:00:25 +0100 Subject: filelist: Fix misinterpretation of C99 inline semantics --- src/filelist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/filelist.c b/src/filelist.c index 453f795..08da331 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -398,7 +398,7 @@ void feh_file_dirname(char *dst, feh_file * f, int maxlen) } #ifdef HAVE_VERSCMP -inline int strcmp_or_strverscmp(const char *s1, const char *s2) +static inline int strcmp_or_strverscmp(const char *s1, const char *s2) { if (!opt.version_sort) return(strcmp(s1, s2)); -- cgit v1.2.3 From 81963c7b44194be63479299f217e97e2d0c48db5 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Thu, 8 Mar 2018 19:42:35 +0100 Subject: add (experimental and still slightly buggy) --inner-geometry feature See #278 --- src/options.c | 5 +++++ src/options.h | 5 +++++ src/winwidget.c | 26 ++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) (limited to 'src') diff --git a/src/options.c b/src/options.c index 3d11482..0db5aae 100644 --- a/src/options.c +++ b/src/options.c @@ -416,6 +416,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"no-recursive" , 0, 0, 241}, {"cache-size" , 1, 0, 243}, {"version-sort" , 0, 0, 246}, + {"inner-geometry", 1, 0, 247}, {0, 0, 0, 0} }; int optch = 0, cmdx = 0; @@ -784,6 +785,10 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) case 246: opt.version_sort = 1; break; + case 247: + opt.inner_geom_flags = XParseGeometry(optarg, &opt.inner_geom_x, + &opt.inner_geom_y, &opt.inner_geom_w, &opt.inner_geom_h); + break; default: break; } diff --git a/src/options.h b/src/options.h index d4de3c5..d4ffbeb 100644 --- a/src/options.h +++ b/src/options.h @@ -111,6 +111,11 @@ struct __fehoptions { int geom_y; unsigned int geom_w; unsigned int geom_h; + int inner_geom_flags; + int inner_geom_x; + int inner_geom_y; + unsigned int inner_geom_w; + unsigned int inner_geom_h; int default_zoom; int zoom_mode; unsigned char adjust_reload; diff --git a/src/winwidget.c b/src/winwidget.c index bb6181a..7b8a9dc 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -555,6 +555,32 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) winwid->im_y = (int) (winwid->h - (winwid->im_h * winwid->zoom)) >> 1; } + /* + * Adjust X/Y offset if the image is larger than the window and + * --inner-geometry is set. This will cause odd behaviour when + * zooming an already large image in --inner-geometry mode, but in most + * cases this should be what the user wants. Plus, it doesn't require + * fiddling around in two or three places above, so it's the best + * solution considering a future refactoring of this function. + */ + + if (need_center || resize) { + if ((opt.inner_geom_flags & XValue) && (winwid->im_w * winwid->zoom) > winwid->w) { + if (opt.inner_geom_flags & XNegative) { + winwid->im_x = winwid->w - (winwid->im_w * winwid->zoom) - opt.inner_geom_x; + } else { + winwid->im_x = - opt.inner_geom_x * winwid->zoom; + } + } + if ((opt.inner_geom_flags & YValue) && (winwid->im_h * winwid->zoom) > winwid->h) { + if (opt.inner_geom_flags & YNegative) { + winwid->im_y = winwid->h - (winwid->im_h * winwid->zoom) - opt.inner_geom_y; + } else { + winwid->im_y = - opt.inner_geom_y * winwid->zoom; + } + } + } + /* Now we ensure only to render the area we're looking at */ dx = winwid->im_x; dy = winwid->im_y; -- cgit v1.2.3 From e522c4ea04e9d899907deb5d0304f7de0823e9da Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Fri, 9 Mar 2018 17:07:52 +0100 Subject: rename --inner-geometry to --offset, discard width and height values --- src/options.c | 6 +++--- src/options.h | 8 +++----- src/winwidget.c | 16 ++++++++-------- 3 files changed, 14 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/options.c b/src/options.c index 0db5aae..bc95604 100644 --- a/src/options.c +++ b/src/options.c @@ -416,7 +416,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"no-recursive" , 0, 0, 241}, {"cache-size" , 1, 0, 243}, {"version-sort" , 0, 0, 246}, - {"inner-geometry", 1, 0, 247}, + {"offset" , 1, 0, 247}, {0, 0, 0, 0} }; int optch = 0, cmdx = 0; @@ -786,8 +786,8 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) opt.version_sort = 1; break; case 247: - opt.inner_geom_flags = XParseGeometry(optarg, &opt.inner_geom_x, - &opt.inner_geom_y, &opt.inner_geom_w, &opt.inner_geom_h); + opt.offset_flags = XParseGeometry(optarg, &opt.offset_x, + &opt.offset_y, (unsigned int *)&discard, (unsigned int *)&discard); break; default: break; diff --git a/src/options.h b/src/options.h index d4ffbeb..ed8641a 100644 --- a/src/options.h +++ b/src/options.h @@ -111,11 +111,9 @@ struct __fehoptions { int geom_y; unsigned int geom_w; unsigned int geom_h; - int inner_geom_flags; - int inner_geom_x; - int inner_geom_y; - unsigned int inner_geom_w; - unsigned int inner_geom_h; + int offset_flags; + int offset_x; + int offset_y; int default_zoom; int zoom_mode; unsigned char adjust_reload; diff --git a/src/winwidget.c b/src/winwidget.c index 7b8a9dc..beae9fa 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -565,18 +565,18 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) */ if (need_center || resize) { - if ((opt.inner_geom_flags & XValue) && (winwid->im_w * winwid->zoom) > winwid->w) { - if (opt.inner_geom_flags & XNegative) { - winwid->im_x = winwid->w - (winwid->im_w * winwid->zoom) - opt.inner_geom_x; + if ((opt.offset_flags & XValue) && (winwid->im_w * winwid->zoom) > winwid->w) { + if (opt.offset_flags & XNegative) { + winwid->im_x = winwid->w - (winwid->im_w * winwid->zoom) - opt.offset_x; } else { - winwid->im_x = - opt.inner_geom_x * winwid->zoom; + winwid->im_x = - opt.offset_x * winwid->zoom; } } - if ((opt.inner_geom_flags & YValue) && (winwid->im_h * winwid->zoom) > winwid->h) { - if (opt.inner_geom_flags & YNegative) { - winwid->im_y = winwid->h - (winwid->im_h * winwid->zoom) - opt.inner_geom_y; + if ((opt.offset_flags & YValue) && (winwid->im_h * winwid->zoom) > winwid->h) { + if (opt.offset_flags & YNegative) { + winwid->im_y = winwid->h - (winwid->im_h * winwid->zoom) - opt.offset_y; } else { - winwid->im_y = - opt.inner_geom_y * winwid->zoom; + winwid->im_y = - opt.offset_y * winwid->zoom; } } } -- cgit v1.2.3 From f8640490308f29de951b7b59f07be8b744f6e895 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sat, 10 Mar 2018 10:03:39 +0100 Subject: Only set random seed once Fixes non-random behaviour when randomizing file lists several times per second. Closes #349 --- src/gib_list.c | 1 - src/imlib.c | 3 --- src/main.c | 2 ++ 3 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/gib_list.c b/src/gib_list.c index 281f528..5384d98 100644 --- a/src/gib_list.c +++ b/src/gib_list.c @@ -360,7 +360,6 @@ gib_list_randomize(gib_list * list) { farray[i] = f; } - srand(getpid() * time(NULL) % ((unsigned int) -1)); for (i = 0; i < len - 1; i++) { r = i + rand() / (RAND_MAX / (len - i) + 1 ); diff --git a/src/imlib.c b/src/imlib.c index d9c5cd0..baaa64a 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -133,9 +133,6 @@ void init_x_and_imlib(void) imlib_set_cache_size(opt.cache_size * 1024 * 1024); - /* Initialise random numbers */ - srand(getpid() * time(NULL) % ((unsigned int) -1)); - return; } diff --git a/src/main.c b/src/main.c index 840919f..534b89e 100644 --- a/src/main.c +++ b/src/main.c @@ -42,6 +42,8 @@ int main(int argc, char **argv) { atexit(feh_clean_exit); + srand(getpid() * time(NULL) % ((unsigned int) -1)); + setup_signal_handlers(); init_parse_options(argc, argv); -- cgit v1.2.3 From 9779f11f4801628b38d17fa78d638f6a75d6257d Mon Sep 17 00:00:00 2001 From: ulteq Date: Fri, 29 Dec 2017 21:27:21 +0100 Subject: Fix zoom ratio calculation This simplifies the logic behind the automatic zoom ratio calculation, which is used by both --auto-zoom and --scale-down. --- src/winwidget.c | 123 +++++++++----------------------------------------------- 1 file changed, 20 insertions(+), 103 deletions(-) (limited to 'src') diff --git a/src/winwidget.c b/src/winwidget.c index beae9fa..a8bcc0a 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -328,6 +328,7 @@ void winwidget_create_window(winwidget ret, int w, int h) opt.geom_h = h; opt.geom_flags |= WidthValue | HeightValue; } + return; } @@ -422,7 +423,6 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) int sx, sy, sw, sh, dx, dy, dw, dh; int calc_w, calc_h; int antialias = 0; - int need_center = winwid->had_resize; if (!winwid->full_screen && resize) { winwidget_resize(winwid, winwid->im_w, winwid->im_h, 0); @@ -438,6 +438,9 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) D(("winwidget_render_image resize %d force_alias %d im %dx%d\n", resize, force_alias, winwid->im_w, winwid->im_h)); + /* winwidget_setup_pixmaps(winwid) resets the winwid->had_resize flag */ + int had_resize = winwid->had_resize || resize; + winwidget_setup_pixmaps(winwid); if (!winwid->full_screen && ((gib_imlib_image_has_alpha(winwid->im)) @@ -447,110 +450,19 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) || (winwid->has_rotated))) feh_draw_checks(winwid); - if (!winwid->full_screen && opt.zoom_mode && (winwid->type != WIN_TYPE_THUMBNAIL) - && (winwid->zoom == 1.0) && ! (opt.geom_flags & (WidthValue | HeightValue)) - && (winwid->w > winwid->im_w) && (winwid->h > winwid->im_h)) - feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, winwid->w, winwid->h); + if (had_resize && !opt.keep_zoom_vp && (winwid->type != WIN_TYPE_THUMBNAIL)) { + double required_zoom = 1.0; + feh_calc_needed_zoom(&required_zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h); - /* - * In case of a resize, the geomflags (and im_w, im_h) get updated by - * the ConfigureNotify handler. - */ - if (need_center && !winwid->full_screen && (winwid->type != WIN_TYPE_THUMBNAIL) - && (opt.geom_flags & (WidthValue | HeightValue)) - && ((winwid->w < winwid->im_w) || (winwid->h < winwid->im_h))) - feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, winwid->w, winwid->h); + winwid->zoom = opt.default_zoom ? (0.01 * opt.default_zoom) : 1.0; + if ((opt.scale_down || (winwid->full_screen && !opt.default_zoom)) + && winwid->zoom > required_zoom) + winwid->zoom = required_zoom; + else if ((opt.zoom_mode && required_zoom > 1) + && (!opt.default_zoom || required_zoom < winwid->zoom)) + winwid->zoom = required_zoom; - if (resize && (winwid->type != WIN_TYPE_THUMBNAIL) && - (winwid->full_screen || (opt.geom_flags & (WidthValue | HeightValue)))) { - int smaller; /* Is the image smaller than screen? */ - int max_w = 0, max_h = 0; - - if (winwid->full_screen) { - max_w = scr->width; - max_h = scr->height; -#ifdef HAVE_LIBXINERAMA - if (opt.xinerama && xinerama_screens) { - max_w = xinerama_screens[xinerama_screen].width; - max_h = xinerama_screens[xinerama_screen].height; - } -#endif /* HAVE_LIBXINERAMA */ - } else { - if (opt.geom_flags & WidthValue) { - max_w = opt.geom_w; - } - if (opt.geom_flags & HeightValue) { - max_h = opt.geom_h; - } - } - - D(("Calculating for fullscreen/fixed geom render\n")); - smaller = ((winwid->im_w < max_w) - && (winwid->im_h < max_h)); - - if (!smaller || opt.zoom_mode) { - /* contributed by Jens Laas - * What it does: - * zooms images by a fixed amount but never larger than the screen. - * - * Why: - * This is nice if you got a collection of images where some - * are small and can stand a small zoom. Large images are unaffected. - * - * When does it work, and how? - * You have to be in fullscreen mode _and_ have auto-zoom turned on. - * "feh -FZ --zoom 130 imagefile" will do the trick. - * -zoom percent - the new switch. - * 100 = orignal size, - * 130 is 30% larger. - */ - if (opt.default_zoom) { - double old_zoom = winwid->zoom; - - winwid->zoom = 0.01 * opt.default_zoom; - if (opt.default_zoom != 100) { - if ((winwid->im_h * winwid->zoom) > max_h) - winwid->zoom = old_zoom; - else if ((winwid->im_w * winwid->zoom) > max_w) - winwid->zoom = old_zoom; - } - - winwid->im_x = ((int) - (max_w - (winwid->im_w * winwid->zoom))) >> 1; - winwid->im_y = ((int) - (max_h - (winwid->im_h * winwid->zoom))) >> 1; - } else { - /* Image is larger than the screen (so wants shrinking), or it's - smaller but wants expanding to fill it */ - double ratio = feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, max_w, max_h); - - if (ratio > 1.0) { - /* height is the factor */ - winwid->im_x = 0; - winwid->im_y = ((int) - (max_h - (winwid->im_h * winwid->zoom))) >> 1; - } else { - /* width is the factor */ - winwid->im_x = ((int) - (max_w - (winwid->im_w * winwid->zoom))) >> 1; - winwid->im_y = 0; - } - } - } else { - /* my modification to jens hack, allow --zoom without auto-zoom mode */ - if (opt.default_zoom) { - winwid->zoom = 0.01 * opt.default_zoom; - } else { - winwid->zoom = 1.0; - } - /* Just center the image in the window */ - winwid->im_x = (int) (max_w - (winwid->im_w * winwid->zoom)) >> 1; - winwid->im_y = (int) (max_h - (winwid->im_h * winwid->zoom)) >> 1; - } - } - else if (need_center && !winwid->full_screen - && (winwid->type != WIN_TYPE_THUMBNAIL) && !opt.keep_zoom_vp) { winwid->im_x = (int) (winwid->w - (winwid->im_w * winwid->zoom)) >> 1; winwid->im_y = (int) (winwid->h - (winwid->im_h * winwid->zoom)) >> 1; } @@ -564,7 +476,7 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) * solution considering a future refactoring of this function. */ - if (need_center || resize) { + if (had_resize) { if ((opt.offset_flags & XValue) && (winwid->im_w * winwid->zoom) > winwid->w) { if (opt.offset_flags & XNegative) { winwid->im_x = winwid->w - (winwid->im_w * winwid->zoom) - opt.offset_x; @@ -581,6 +493,11 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) } } + winwid->had_resize = 0; + + if (opt.keep_zoom_vp) + winwidget_sanitise_offsets(winwid); + /* Now we ensure only to render the area we're looking at */ dx = winwid->im_x; dy = winwid->im_y; -- cgit v1.2.3 From acada1a7153a43f4fd18cfb15ac7b0278e0d4727 Mon Sep 17 00:00:00 2001 From: ulteq Date: Fri, 9 Mar 2018 16:21:06 +0100 Subject: Allow empty string as --geometry argument Passing an empty string to the --geometry option will enable fixed geometry mode without having to specify anything else --- src/options.c | 1 + src/options.h | 1 + src/winwidget.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/options.c b/src/options.c index bc95604..1e75c6b 100644 --- a/src/options.c +++ b/src/options.c @@ -592,6 +592,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) opt.filelistfile = estrdup(optarg); break; case 'g': + opt.geom_enabled = 1; opt.geom_flags = XParseGeometry(optarg, &opt.geom_x, &opt.geom_y, &opt.geom_w, &opt.geom_h); break; diff --git a/src/options.h b/src/options.h index ed8641a..6ad8a44 100644 --- a/src/options.h +++ b/src/options.h @@ -106,6 +106,7 @@ struct __fehoptions { int sort; int version_sort; int debug; + int geom_enabled; int geom_flags; int geom_x; int geom_y; diff --git a/src/winwidget.c b/src/winwidget.c index a8bcc0a..1ce7e61 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -323,7 +323,7 @@ void winwidget_create_window(winwidget ret, int w, int h) winwidget_register(ret); /* do not scale down a thumbnail list window, only those created from it */ - if (opt.scale_down && (ret->type != WIN_TYPE_THUMBNAIL)) { + if (opt.geom_enabled && (ret->type != WIN_TYPE_THUMBNAIL)) { opt.geom_w = w; opt.geom_h = h; opt.geom_flags |= WidthValue | HeightValue; -- cgit v1.2.3 From 4f347623187269bf959d8cfe1ee70da1c8262d33 Mon Sep 17 00:00:00 2001 From: ulteq Date: Thu, 11 Jan 2018 10:51:43 +0100 Subject: Fix draw checks condition --- src/winwidget.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/winwidget.c b/src/winwidget.c index 1ce7e61..a928a18 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -445,8 +445,9 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) if (!winwid->full_screen && ((gib_imlib_image_has_alpha(winwid->im)) || (opt.geom_flags & (WidthValue | HeightValue)) - || (winwid->im_x || winwid->im_y) || (winwid->zoom != 1.0) - || (winwid->w > winwid->im_w || winwid->h > winwid->im_h) + || (winwid->im_x || winwid->im_y) + || (winwid->w > winwid->im_w * winwid->zoom) + || (winwid->h > winwid->im_h * winwid->zoom) || (winwid->has_rotated))) feh_draw_checks(winwid); -- cgit v1.2.3 From 81d0a386e27d044987308a1a66a1a623175fbc4a Mon Sep 17 00:00:00 2001 From: ulteq Date: Thu, 11 Jan 2018 10:52:55 +0100 Subject: Run draw checks after zoom calculation --- src/winwidget.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/winwidget.c b/src/winwidget.c index a928a18..7ac641a 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -443,14 +443,6 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) winwidget_setup_pixmaps(winwid); - if (!winwid->full_screen && ((gib_imlib_image_has_alpha(winwid->im)) - || (opt.geom_flags & (WidthValue | HeightValue)) - || (winwid->im_x || winwid->im_y) - || (winwid->w > winwid->im_w * winwid->zoom) - || (winwid->h > winwid->im_h * winwid->zoom) - || (winwid->has_rotated))) - feh_draw_checks(winwid); - if (had_resize && !opt.keep_zoom_vp && (winwid->type != WIN_TYPE_THUMBNAIL)) { double required_zoom = 1.0; feh_calc_needed_zoom(&required_zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h); @@ -499,6 +491,14 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) if (opt.keep_zoom_vp) winwidget_sanitise_offsets(winwid); + if (!winwid->full_screen && ((gib_imlib_image_has_alpha(winwid->im)) + || (opt.geom_flags & (WidthValue | HeightValue)) + || (winwid->im_x || winwid->im_y) + || (winwid->w > winwid->im_w * winwid->zoom) + || (winwid->h > winwid->im_h * winwid->zoom) + || (winwid->has_rotated))) + feh_draw_checks(winwid); + /* Now we ensure only to render the area we're looking at */ dx = winwid->im_x; dy = winwid->im_y; -- cgit v1.2.3 From 6407071aa3d4a213565b0e47fc14c06848a7d582 Mon Sep 17 00:00:00 2001 From: ulteq Date: Thu, 11 Jan 2018 10:59:45 +0100 Subject: Remove duplicate bounds checking --- src/winwidget.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src') diff --git a/src/winwidget.c b/src/winwidget.c index 7ac641a..917e74d 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -429,12 +429,6 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) winwidget_reset_image(winwid); } - /* bounds checks for panning */ - if (winwid->im_x > winwid->w) - winwid->im_x = winwid->w; - if (winwid->im_y > winwid->h) - winwid->im_y = winwid->h; - D(("winwidget_render_image resize %d force_alias %d im %dx%d\n", resize, force_alias, winwid->im_w, winwid->im_h)); -- cgit v1.2.3 From 30c40b7e7fc573e1bda6264c507e4883791a1c05 Mon Sep 17 00:00:00 2001 From: ulteq Date: Fri, 29 Dec 2017 12:34:48 +0100 Subject: Fix window auto-resize with --keep-zoom-vp enabled --keep-zoom-vp will no longer block the dynamic window resizing mechanism. --- src/slideshow.c | 10 ++-------- src/winwidget.c | 3 ++- 2 files changed, 4 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/slideshow.c b/src/slideshow.c index effdcaf..071cb29 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -223,10 +223,8 @@ void feh_reload_image(winwidget w, int resize, int force_new) 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_render_image(w, resize, 0); return; } @@ -386,11 +384,7 @@ void slideshow_change_image(winwidget winwid, int change, int render) winwid->zoom = tzoom; } if (render) { - if (opt.keep_zoom_vp) { - winwidget_render_image(winwid, 0, 0); - } else { - winwidget_render_image(winwid, 1, 0); - } + winwidget_render_image(winwid, 1, 0); } break; } else diff --git a/src/winwidget.c b/src/winwidget.c index 917e74d..3c90b57 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -426,7 +426,8 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) if (!winwid->full_screen && resize) { winwidget_resize(winwid, winwid->im_w, winwid->im_h, 0); - winwidget_reset_image(winwid); + if (!opt.keep_zoom_vp) + winwidget_reset_image(winwid); } D(("winwidget_render_image resize %d force_alias %d im %dx%d\n", -- cgit v1.2.3 From d9c1cab85af4107cde67a2aba5657fc0b680f852 Mon Sep 17 00:00:00 2001 From: ulteq Date: Fri, 12 Jan 2018 17:59:40 +0100 Subject: Fix --screen-clip window dimension calculation --- src/winwidget.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/winwidget.c b/src/winwidget.c index 3c90b57..576ff58 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -820,8 +820,12 @@ void winwidget_resize(winwidget winwid, int w, int h, int force_resize) if (winwid && ((winwid->w != w) || (winwid->h != h))) { /* winwidget_clear_background(winwid); */ if (opt.screen_clip) { - winwid->w = (w > scr_width) ? scr_width : w; - winwid->h = (h > scr_height) ? scr_height : h; + double required_zoom = 1.0; + int max_w = (w > scr_width) ? scr_width : w; + int max_h = (h > scr_height) ? scr_height : h; + feh_calc_needed_zoom(&required_zoom, winwid->im_w, winwid->im_h, max_w, max_h); + winwid->w = winwid->im_w * required_zoom; + winwid->h = winwid->im_h * required_zoom; } if (winwid->full_screen) { XTranslateCoordinates(disp, winwid->win, attributes.root, -- cgit v1.2.3 From b71d8407eea710d654438f423b6f56eb323ee5d2 Mon Sep 17 00:00:00 2001 From: ulteq Date: Wed, 17 Jan 2018 09:45:09 +0100 Subject: Remove unused code --- src/winwidget.c | 8 -------- src/winwidget.h | 1 - 2 files changed, 9 deletions(-) (limited to 'src') diff --git a/src/winwidget.c b/src/winwidget.c index 576ff58..39d7d7b 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -645,13 +645,6 @@ Pixmap feh_create_checks(void) return(checks_pmap); } -void winwidget_clear_background(winwidget w) -{ - XSetWindowBackgroundPixmap(disp, w->win, feh_create_checks()); - /* XClearWindow(disp, w->win); */ - return; -} - void feh_draw_checks(winwidget win) { static GC gc = None; @@ -818,7 +811,6 @@ void winwidget_resize(winwidget winwid, int w, int h, int force_resize) return; } if (winwid && ((winwid->w != w) || (winwid->h != h))) { - /* winwidget_clear_background(winwid); */ if (opt.screen_clip) { double required_zoom = 1.0; int max_w = (w > scr_width) ? scr_width : w; diff --git a/src/winwidget.h b/src/winwidget.h index dd8489a..280c977 100644 --- a/src/winwidget.h +++ b/src/winwidget.h @@ -146,7 +146,6 @@ winwidget winwidget_create_from_image(Imlib_Image im, char type); void winwidget_rename(winwidget winwid, char *newname); void winwidget_destroy(winwidget winwid); void winwidget_create_window(winwidget ret, int w, int h); -void winwidget_clear_background(winwidget w); Pixmap feh_create_checks(void); double feh_calc_needed_zoom(double *zoom, int orig_w, int orig_h, int dest_w, int dest_h); void feh_debug_print_winwid(winwidget winwid); -- cgit v1.2.3 From f111cef018432cd12d9989c4f8b4ecd3dfa186bb Mon Sep 17 00:00:00 2001 From: ulteq Date: Wed, 17 Jan 2018 09:57:36 +0100 Subject: Fix indentation --- src/winwidget.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/winwidget.c b/src/winwidget.c index 39d7d7b..1ea6e9c 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -806,10 +806,10 @@ void winwidget_resize(winwidget winwid, int w, int h, int force_resize) D((" x %d y %d w %d h %d\n", attributes.x, attributes.y, winwid->w, winwid->h)); - if ((opt.geom_flags & (WidthValue | HeightValue)) && !force_resize) { - winwid->had_resize = 1; - return; - } + if ((opt.geom_flags & (WidthValue | HeightValue)) && !force_resize) { + winwid->had_resize = 1; + return; + } if (winwid && ((winwid->w != w) || (winwid->h != h))) { if (opt.screen_clip) { double required_zoom = 1.0; @@ -820,13 +820,12 @@ void winwidget_resize(winwidget winwid, int w, int h, int force_resize) winwid->h = winwid->im_h * required_zoom; } if (winwid->full_screen) { - XTranslateCoordinates(disp, winwid->win, attributes.root, - -attributes.border_width - - attributes.x, - -attributes.border_width - attributes.y, &tc_x, &tc_y, &dw); - winwid->x = tc_x; - winwid->y = tc_y; - XMoveResizeWindow(disp, winwid->win, tc_x, tc_y, winwid->w, winwid->h); + XTranslateCoordinates(disp, winwid->win, attributes.root, + -attributes.border_width - attributes.x, + -attributes.border_width - attributes.y, &tc_x, &tc_y, &dw); + winwid->x = tc_x; + winwid->y = tc_y; + XMoveResizeWindow(disp, winwid->win, tc_x, tc_y, winwid->w, winwid->h); } else XResizeWindow(disp, winwid->win, winwid->w, winwid->h); -- cgit v1.2.3 From 0235156ba92bff1f9b023a2fd91540bfca66ce1b Mon Sep 17 00:00:00 2001 From: ulteq Date: Thu, 25 Jan 2018 15:03:45 +0100 Subject: Simplify --keep-zoom-vp handling --- src/slideshow.c | 37 ------------------------------------- src/winwidget.c | 13 +++++++------ 2 files changed, 7 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/slideshow.c b/src/slideshow.c index 071cb29..f3860ed 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -143,16 +143,6 @@ 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); @@ -217,13 +207,6 @@ 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); } - 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, resize, 0); return; @@ -239,11 +222,6 @@ void slideshow_change_image(winwidget winwid, int change, int render) */ int our_filelist_len = filelist_len; - 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) @@ -354,14 +332,6 @@ 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))) { int w = gib_imlib_image_get_width(winwid->im); int h = gib_imlib_image_get_height(winwid->im); @@ -376,13 +346,6 @@ void slideshow_change_image(winwidget winwid, int change, int render) winwidget_reset_image(winwid); winwid->im_w = w; winwid->im_h = h; - 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) { winwidget_render_image(winwid, 1, 0); } diff --git a/src/winwidget.c b/src/winwidget.c index 1ea6e9c..03aa9e8 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -426,8 +426,7 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) if (!winwid->full_screen && resize) { winwidget_resize(winwid, winwid->im_w, winwid->im_h, 0); - if (!opt.keep_zoom_vp) - winwidget_reset_image(winwid); + winwidget_reset_image(winwid); } D(("winwidget_render_image resize %d force_alias %d im %dx%d\n", @@ -953,10 +952,12 @@ void feh_debug_print_winwid(winwidget w) void winwidget_reset_image(winwidget winwid) { - winwid->zoom = 1.0; - winwid->old_zoom = 1.0; - winwid->im_x = 0; - winwid->im_y = 0; + if (!opt.keep_zoom_vp) { + winwid->zoom = 1.0; + winwid->old_zoom = 1.0; + winwid->im_x = 0; + winwid->im_y = 0; + } winwid->im_angle = 0.0; winwid->has_rotated = 0; return; -- cgit v1.2.3 From 701cf1377fa37a1d0c6556eeaf12118c73f4f841 Mon Sep 17 00:00:00 2001 From: ulteq Date: Sat, 10 Mar 2018 21:28:32 +0100 Subject: Adapt the new --offset option --- src/winwidget.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/winwidget.c b/src/winwidget.c index 03aa9e8..4374752 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -450,33 +450,23 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) && (!opt.default_zoom || required_zoom < winwid->zoom)) winwid->zoom = required_zoom; - winwid->im_x = (int) (winwid->w - (winwid->im_w * winwid->zoom)) >> 1; - winwid->im_y = (int) (winwid->h - (winwid->im_h * winwid->zoom)) >> 1; - } - - /* - * Adjust X/Y offset if the image is larger than the window and - * --inner-geometry is set. This will cause odd behaviour when - * zooming an already large image in --inner-geometry mode, but in most - * cases this should be what the user wants. Plus, it doesn't require - * fiddling around in two or three places above, so it's the best - * solution considering a future refactoring of this function. - */ - - if (had_resize) { - if ((opt.offset_flags & XValue) && (winwid->im_w * winwid->zoom) > winwid->w) { + if (opt.offset_flags & XValue) { if (opt.offset_flags & XNegative) { winwid->im_x = winwid->w - (winwid->im_w * winwid->zoom) - opt.offset_x; } else { winwid->im_x = - opt.offset_x * winwid->zoom; } + } else { + winwid->im_x = (int) (winwid->w - (winwid->im_w * winwid->zoom)) >> 1; } - if ((opt.offset_flags & YValue) && (winwid->im_h * winwid->zoom) > winwid->h) { + if (opt.offset_flags & YValue) { if (opt.offset_flags & YNegative) { winwid->im_y = winwid->h - (winwid->im_h * winwid->zoom) - opt.offset_y; } else { winwid->im_y = - opt.offset_y * winwid->zoom; } + } else { + winwid->im_y = (int) (winwid->h - (winwid->im_h * winwid->zoom)) >> 1; } } -- cgit v1.2.3 From 1e212f65c87fd634c738b4c79e1ffed5c29b039d Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 4 Apr 2018 08:35:11 +0200 Subject: Add %g and %Z format specifiers (closes #391) --- man/feh.pre | 13 +++++++++++-- src/slideshow.c | 12 ++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/man/feh.pre b/man/feh.pre index eb31f37..cc67b25 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -1014,6 +1014,10 @@ Image path/filename Escaped image path/filename .Pq for use in shell commands . +.It %g +. +w,h window dimensions in pixels (mnemonic: geometry) +. .It %h . Image height @@ -1048,8 +1052,9 @@ Number of image pixels . .It \&%P . -Number of image pixels +Number of image pixels in human-readable format with k/M .Pq kilopixels / megapixels +suffix . .It %r . @@ -1087,7 +1092,11 @@ Process ID . .It %z . -current image zoom +Current image zoom, rounded to two decimal places +. +.It %Z +. +Current image zoom, higher precision . .It %% . diff --git a/src/slideshow.c b/src/slideshow.c index effdcaf..7bad2c9 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -468,6 +468,12 @@ char *feh_printf(char *str, feh_file * file, winwidget winwid) if (file) strncat(ret, shell_escape(file->filename), sizeof(ret) - strlen(ret) - 1); break; + case 'g': + if (winwid) { + snprintf(buf, sizeof(buf), "%d,%d", winwid->w, winwid->h); + strncat(ret, buf, sizeof(ret) - strlen(ret) - 1); + } + break; case 'h': if (file && (file->info || !feh_file_info_load(file, NULL))) { snprintf(buf, sizeof(buf), "%d", file->info->height); @@ -564,6 +570,12 @@ char *feh_printf(char *str, feh_file * file, winwidget winwid) strncat(ret, "1.00", sizeof(ret) - strlen(ret) - 1); } break; + case 'Z': + if (winwid) { + snprintf(buf, sizeof(buf), "%f", winwid->zoom); + strncat(ret, buf, sizeof(ret) - strlen(ret) - 1); + } + break; case '%': strncat(ret, "%", sizeof(ret) - strlen(ret) - 1); break; -- cgit v1.2.3 From b05b89f404d44e2e2b3e675ccac09cfa7593eef4 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 18 Apr 2018 21:07:33 +0200 Subject: Always save absolute paths in ~/fehbg (closes #389) --- src/wallpaper.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wallpaper.c b/src/wallpaper.c index 2d3d3bc..8d15335 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -453,7 +453,9 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, if (home) { FILE *fp; char *path; + char *absolute_path; struct stat s; + gib_list *filelist_pos = filelist; path = estrjoin("/", home, ".fehbg", NULL); if ((fp = fopen(path, "w")) == NULL) { weprintf("Can't write to %s", path); @@ -461,7 +463,16 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, fputs("#!/bin/sh\n", fp); if (use_filelist) { for (int i = 0; i < cmdargc; i++) { - fputs(shell_escape(cmdargv[i]), fp); + if (filelist_pos && !strcmp(FEH_FILE(filelist_pos->data)->filename, cmdargv[i])) { + /* argument is a file */ + absolute_path = feh_absolute_path(cmdargv[i]); + fputs(shell_escape(absolute_path), fp); + filelist_pos = filelist_pos->next; + free(absolute_path); + } else { + /* argument is an option / option arg */ + fputs(shell_escape(cmdargv[i]), fp); + } fputc(' ', fp); } } else if (fil) { @@ -482,7 +493,9 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, fputs(" --no-xinerama", fp); #endif fputc(' ', fp); - fputs(shell_escape(fil), fp); + absolute_path = feh_absolute_path(fil); + fputs(shell_escape(absolute_path), fp); + free(absolute_path); } fputc('\n', fp); fclose(fp); -- cgit v1.2.3 From f68160e7fb3c86bfa14f8ea7faf0f3d104f4a457 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Thu, 10 May 2018 21:16:00 +0200 Subject: Only save background setting-related options in ~/.fehbg This restores pre-2.21 ~/.fehbg behaviour. Replicating the entire commandline in ~/.fehbg turned out to do more harm than good. Closes #398 --- man/feh.pre | 8 -------- src/wallpaper.c | 56 +++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 35 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/man/feh.pre b/man/feh.pre index 01b6377..a6b76ef 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -965,14 +965,6 @@ So to have your background restored every time you start X, you can add .Qq ~/.fehbg & to your X startup script .Pq such as Pa ~/.xinitrc . -Note that -.Pq unless the wallpaper is set via the menu -.Nm -saves the files and directories it was passed on the commandline, not the -files which actually ended up as wallpaper. -So, if you have randomization enabled, -.Pa ~/.fehbg -may set different wallpapers on each execution. . .Pp . diff --git a/src/wallpaper.c b/src/wallpaper.c index 8d15335..4eaa660 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -461,6 +461,40 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, weprintf("Can't write to %s", path); } else { fputs("#!/bin/sh\n", fp); + fputs(cmdargv[0], fp); + fputs(" --bg-", fp); + if (centered) + fputs("center", fp); + else if (scaled) + fputs("scale", fp); + else if (filled) + fputs("fill", fp); + else + fputs("tile", fp); +#ifdef HAVE_LIBXINERAMA + if (opt.xinerama) { + if (opt.xinerama_index >= 0) { + fprintf(fp, " --xinerama-index %d", opt.xinerama_index); + } + } + else { + fputs(" --no-xinerama", fp); + } +#endif /* HAVE_LIBXINERAMA */ + if (opt.geom_flags & XValue) { + fprintf(fp, " --geometry %c%d", + opt.geom_flags & XNegative ? '-' : '+', + opt.geom_flags & XNegative ? abs(opt.geom_x) : opt.geom_x); + if (opt.geom_flags & YValue) { + fprintf(fp, "%c%d", + opt.geom_flags & YNegative ? '-' : '+', + opt.geom_flags & YNegative ? abs(opt.geom_y) : opt.geom_y); + } + } + if (opt.force_aliasing) { + fputs(" --force-aliasing", fp); + } + fputc(' ', fp); if (use_filelist) { for (int i = 0; i < cmdargc; i++) { if (filelist_pos && !strcmp(FEH_FILE(filelist_pos->data)->filename, cmdargv[i])) { @@ -469,30 +503,10 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, fputs(shell_escape(absolute_path), fp); filelist_pos = filelist_pos->next; free(absolute_path); - } else { - /* argument is an option / option arg */ - fputs(shell_escape(cmdargv[i]), fp); + fputc(' ', fp); } - fputc(' ', fp); } } else if (fil) { - fputs("feh --bg-", fp); - if (centered) - fputs("center", fp); - else if (scaled) - fputs("scale", fp); - else if (filled) - fputs("fill", fp); - else - fputs("tile", fp); - - if (opt.force_aliasing) - fputs(" --force-aliasing", fp); -#ifdef HAVE_LIBXINERAMA - if (!opt.xinerama) - fputs(" --no-xinerama", fp); -#endif - fputc(' ', fp); absolute_path = feh_absolute_path(fil); fputs(shell_escape(absolute_path), fp); free(absolute_path); -- cgit v1.2.3 From 4e2e218cf0fffd0c74aa4bd44d7abd318166403f Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Thu, 10 May 2018 21:23:28 +0200 Subject: Save image-bg setting in ~/.fehbg --- src/wallpaper.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/wallpaper.c b/src/wallpaper.c index 4eaa660..6aa5c6d 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -471,6 +471,10 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, fputs("fill", fp); else fputs("tile", fp); + if (opt.image_bg) { + fputs(" --image-bg ", fp); + fputs(opt.image_bg, fp); + } #ifdef HAVE_LIBXINERAMA if (opt.xinerama) { if (opt.xinerama_index >= 0) { -- cgit v1.2.3 From e28fb4e9d5723c46b8c3c91e94e9c5789b609d80 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Fri, 11 May 2018 15:03:24 +0200 Subject: Use custom temporary directory for ImageMagick calls and clean it up afterwards --- man/feh.pre | 15 --------------- src/imlib.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/man/feh.pre b/man/feh.pre index a6b76ef..a358714 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -489,11 +489,6 @@ of zero causes to try indefinitely. By default, magick support is disabled. . -Note that feh may clutter -.Pa /tmp -with temporary files created by ImageMagick for each failed conversion attempt. -This is a known bug. -. .It Cm --max-dimension Ar width No x Ar height . Only show images with width <= @@ -1916,16 +1911,6 @@ as it could be. does not take window decorations into account and may therefore make the window slightly too large. . -.Pp -. -When enabled, -.Cm --magick-timeout -may clutter -.Pa /tmp -with temporary files produced by ImageMagick. -This happens whenever an image is not loaded due to the conversion taking -longer than the specified timeout. -. .Ss REPORTING BUGS . If you find a bug, please report it to diff --git a/src/imlib.c b/src/imlib.c index baaa64a..28dc1a6 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -304,8 +304,10 @@ static char *feh_magick_load_image(char *filename) char *basename; char *tmpname; char *sfn; + char tempdir[] = "/tmp/.feh-magick-tmp-XXXXXX"; int fd = -1, devnull = -1; int status; + char created_tempdir = 0; if (opt.magick_timeout < 0) return NULL; @@ -339,6 +341,22 @@ static char *feh_magick_load_image(char *filename) */ argv_fn = estrjoin(":", "png", sfn, NULL); + /* + * By default, ImageMagick saves (occasionally lots of) temporary files + * in /tmp. It doesn't remove them if it runs into a timeout and is killed + * by us, no matter whether we use SIGINT, SIGTERM or SIGKILL. So, unless + * MAGICK_TMPDIR has already been set by the user, we create our own + * temporary directory for ImageMagick and remove its contents at the end of + * this function. + */ + if (getenv("MAGICK_TMPDIR") == NULL) { + if (mkdtemp(tempdir) == NULL) { + weprintf("%s: ImageMagick may leave temporary files in /tmp. mkdtemp failed:", filename); + } else { + created_tempdir = 1; + } + } + if ((childpid = fork()) < 0) { weprintf("%s: Can't load with imagemagick. Fork failed:", filename); unlink(sfn); @@ -360,6 +378,11 @@ static char *feh_magick_load_image(char *filename) */ setpgid(0, 0); + if (created_tempdir) { + // no error checking - this is a best-effort code path + setenv("MAGICK_TMPDIR", tempdir, 0); + } + execlp("convert", "convert", filename, argv_fn, NULL); _exit(1); } @@ -373,13 +396,39 @@ static char *feh_magick_load_image(char *filename) sfn = NULL; if (!opt.quiet) { - weprintf("%s - Conversion took too long, skipping", filename); + weprintf("%s: Conversion took too long, skipping", filename); } } close(fd); childpid = 0; } + if (created_tempdir) { + DIR *dir; + struct dirent *de; + if ((dir = opendir(tempdir)) == NULL) { + weprintf("%s: Cannot remove temporary ImageMagick files from %s:", filename, tempdir); + } else { + while ((de = readdir(dir)) != NULL) { + if (de->d_name[0] != '.') { + char *temporary_file_name = estrjoin("/", tempdir, de->d_name, NULL); + /* + * We assume that ImageMagick only creates temporary files and + * not directories. + */ + if (unlink(temporary_file_name) == -1) { + weprintf("unlink %s:", temporary_file_name); + } + free(temporary_file_name); + } + } + if (rmdir(tempdir) == -1) { + weprintf("rmdir %s:", tempdir); + } + } + closedir(dir); + } + free(argv_fn); return sfn; } -- cgit v1.2.3 From 185e861b4975bf2e5505ac7237f6946ee4def608 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Fri, 11 May 2018 17:03:34 +0200 Subject: Show correct filelist position in windows opened from thumbnail mode Addresses part of issue #75 --- src/thumbnail.c | 15 ++++++++++++--- src/winwidget.c | 2 -- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/thumbnail.c b/src/thumbnail.c index 003c7b4..3e99bfb 100644 --- a/src/thumbnail.c +++ b/src/thumbnail.c @@ -766,17 +766,26 @@ int feh_thumbnail_get_generated(Imlib_Image * image, feh_file * file, void feh_thumbnail_show_fullsize(feh_file *thumbfile) { winwidget thumbwin = NULL; + gib_list *l; + + for (l = filelist; l; l = l->next) { + if (FEH_FILE(l->data) == thumbfile) { + break; + } + } + if (!l) { + eprintf("Cannot find %s in filelist, wtf", thumbfile->filename); + } thumbwin = winwidget_get_first_window_of_type(WIN_TYPE_THUMBNAIL_VIEWER); if (!thumbwin) { thumbwin = winwidget_create_from_file( - gib_list_add_front(NULL, thumbfile), + l, WIN_TYPE_THUMBNAIL_VIEWER); if (thumbwin) winwidget_show(thumbwin); } else if (FEH_FILE(thumbwin->file->data) != thumbfile) { - free(thumbwin->file); - thumbwin->file = gib_list_add_front(NULL, thumbfile); + thumbwin->file = l; feh_reload_image(thumbwin, 1, 1); } } diff --git a/src/winwidget.c b/src/winwidget.c index beae9fa..7aae191 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -773,8 +773,6 @@ void winwidget_destroy(winwidget winwid) free(winwid->name); if (winwid->gc) XFreeGC(disp, winwid->gc); - if ((winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) && (winwid->file != NULL)) - gib_list_free(winwid->file); if (winwid->im) gib_imlib_free_image_and_decache(winwid->im); free(winwid); -- cgit v1.2.3 From fb5eac4ae56a7b77475f426a0874498897ff45ec Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Fri, 11 May 2018 17:36:00 +0200 Subject: Handle some Esc-based keys from stdin (arrow keys and Alt+X for now) --- src/keyevents.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/keyevents.c b/src/keyevents.c index 933d887..12a8eb9 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -317,6 +317,7 @@ void feh_event_invoke_action(winwidget winwid, unsigned char action) void feh_event_handle_stdin() { char stdin_buf[2]; + static char is_esc = 0; KeySym keysym = NoSymbol; if (read(STDIN_FILENO, &stdin_buf, 1) == -1) { control_via_stdin = 0; @@ -328,17 +329,40 @@ void feh_event_handle_stdin() } stdin_buf[1] = '\0'; + // escape? + if (stdin_buf[0] == 0x1b) { + is_esc = 1; + return; + } + if ((is_esc == 1) && (stdin_buf[0] == '[')) { + is_esc = 2; + return; + } + if (stdin_buf[0] == ' ') keysym = XK_space; else if (stdin_buf[0] == '\n') keysym = XK_Return; else if ((stdin_buf[0] == '\b') || (stdin_buf[0] == 127)) keysym = XK_BackSpace; + else if (is_esc == 2) { + if (stdin_buf[0] == 'A') + keysym = XK_Up; + else if (stdin_buf[0] == 'B') + keysym = XK_Down; + else if (stdin_buf[0] == 'C') + keysym = XK_Right; + else if (stdin_buf[0] == 'D') + keysym = XK_Left; + is_esc = 0; + } else keysym = XStringToKeysym(stdin_buf); if (window_num) - feh_event_handle_generic(windows[0], 0, keysym, 0); + feh_event_handle_generic(windows[0], is_esc * Mod1Mask, keysym, 0); + + is_esc = 0; } void feh_event_handle_keypress(XEvent * ev) -- cgit v1.2.3 From 3c675a64a5842f0fe824a22bc9d3af025c1d17fe Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Fri, 11 May 2018 20:51:24 +0200 Subject: Update copyright notice --- man/feh.pre | 2 +- src/collage.c | 2 +- src/debug.h | 2 +- src/events.c | 2 +- src/feh.h | 2 +- src/filelist.c | 2 +- src/imlib.c | 2 +- src/index.c | 2 +- src/index.h | 2 +- src/keyevents.c | 2 +- src/list.c | 2 +- src/main.c | 2 +- src/menu.c | 2 +- src/menu.h | 2 +- src/options.c | 2 +- src/options.h | 2 +- src/signals.c | 2 +- src/slideshow.c | 2 +- src/structs.h | 2 +- src/thumbnail.c | 2 +- src/thumbnail.h | 2 +- src/timers.c | 2 +- src/wallpaper.c | 2 +- src/wallpaper.h | 2 +- src/winwidget.c | 2 +- src/winwidget.h | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/man/feh.pre b/man/feh.pre index a358714..d2c2cea 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -1943,7 +1943,7 @@ Make zoom options more intuitive . Copyright (C) 1999, 2000 by Paul Duncan. Copyright (C) 1999, 2000 by Tom Gilbert (and various contributors). -Copyright (C) 2010-2016 by Daniel Friesel (and even more contributors). +Copyright (C) 2010-2018 by Daniel Friesel (and even more contributors). . .Pp . diff --git a/src/collage.c b/src/collage.c index 431d3b6..2a4d9f9 100644 --- a/src/collage.c +++ b/src/collage.c @@ -1,7 +1,7 @@ /* collage.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/debug.h b/src/debug.h index eb929e3..38cf83f 100644 --- a/src/debug.h +++ b/src/debug.h @@ -1,7 +1,7 @@ /* debug.h Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/events.c b/src/events.c index 947e69f..4a24935 100644 --- a/src/events.c +++ b/src/events.c @@ -1,7 +1,7 @@ /* events.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/feh.h b/src/feh.h index 3e0cdda..009f45b 100644 --- a/src/feh.h +++ b/src/feh.h @@ -1,7 +1,7 @@ /* feh.h Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/filelist.c b/src/filelist.c index 08da331..eb8e294 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -1,7 +1,7 @@ /* filelist.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/imlib.c b/src/imlib.c index 28dc1a6..5be0539 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -1,7 +1,7 @@ /* imlib.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/index.c b/src/index.c index c8c34c5..ca1664b 100644 --- a/src/index.c +++ b/src/index.c @@ -1,7 +1,7 @@ /* index.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/index.h b/src/index.h index 08ab337..b022f1a 100644 --- a/src/index.h +++ b/src/index.h @@ -1,6 +1,6 @@ /* index.h -Copyright (C) 2011 Daniel Friesel. +Copyright (C) 2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/keyevents.c b/src/keyevents.c index 12a8eb9..689aebd 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -1,7 +1,7 @@ /* keyevents.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/list.c b/src/list.c index 09b23f4..2f6cf76 100644 --- a/src/list.c +++ b/src/list.c @@ -1,7 +1,7 @@ /* list.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/main.c b/src/main.c index 534b89e..f1fca24 100644 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,7 @@ /* main.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/menu.c b/src/menu.c index ddb2db1..2f8875d 100644 --- a/src/menu.c +++ b/src/menu.c @@ -1,7 +1,7 @@ /* menu.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/menu.h b/src/menu.h index 403728f..b53b32f 100644 --- a/src/menu.h +++ b/src/menu.h @@ -1,7 +1,7 @@ /* menu.h Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/options.c b/src/options.c index bc95604..8ddf2fa 100644 --- a/src/options.c +++ b/src/options.c @@ -1,7 +1,7 @@ /* options.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/options.h b/src/options.h index ed8641a..61de5dc 100644 --- a/src/options.h +++ b/src/options.h @@ -1,7 +1,7 @@ /* options.h Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/signals.c b/src/signals.c index 8a3a8f7..c08d5df 100644 --- a/src/signals.c +++ b/src/signals.c @@ -1,6 +1,6 @@ /* signals.c -Copyright (C) 2010 by Daniel Friesel +Copyright (C) 2010-2018 by Daniel Friesel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/slideshow.c b/src/slideshow.c index 7bad2c9..0e560d8 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -1,7 +1,7 @@ /* slideshow.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/structs.h b/src/structs.h index 3942bc0..ce30eb9 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,7 +1,7 @@ /* structs.h Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/thumbnail.c b/src/thumbnail.c index 3e99bfb..cf38cfc 100644 --- a/src/thumbnail.c +++ b/src/thumbnail.c @@ -1,7 +1,7 @@ /* thumbnail.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/thumbnail.h b/src/thumbnail.h index f22ff77..09cd771 100644 --- a/src/thumbnail.h +++ b/src/thumbnail.h @@ -1,7 +1,7 @@ /* thumbnail.h Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/timers.c b/src/timers.c index 1cac94b..95fc9f8 100644 --- a/src/timers.c +++ b/src/timers.c @@ -1,7 +1,7 @@ /* timers.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/wallpaper.c b/src/wallpaper.c index 6aa5c6d..7cf2468 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -1,7 +1,7 @@ /* wallpaper.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/wallpaper.h b/src/wallpaper.h index 0921129..02a6997 100644 --- a/src/wallpaper.h +++ b/src/wallpaper.h @@ -1,7 +1,7 @@ /* wallpaper.h Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/winwidget.c b/src/winwidget.c index 7aae191..cd5a745 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -1,7 +1,7 @@ /* winwidget.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/winwidget.h b/src/winwidget.h index dd8489a..3d998b4 100644 --- a/src/winwidget.h +++ b/src/winwidget.h @@ -1,7 +1,7 @@ /* winwidget.h Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to -- cgit v1.2.3 From 44148026914b06417037f0d4fe6f714f99d1d687 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Fri, 11 May 2018 23:17:59 +0200 Subject: Do not push menus off the screen when hitting screen limits Closes #279 --- src/events.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/events.c b/src/events.c index 4a24935..89eaab8 100644 --- a/src/events.c +++ b/src/events.c @@ -509,6 +509,8 @@ static void feh_event_handle_MotionNotify(XEvent * ev) dy = scr_height - (m->y + m->h); dx = dx < 0 ? dx : 0; dy = dy < 0 ? dy : 0; + dx = m->x + dx < 0 ? -m->x : dx; + dy = m->y + dy < 0 ? -m->y : dy; if (dx || dy) feh_menu_slide_all_menus_relative(dx, dy); } @@ -521,6 +523,8 @@ static void feh_event_handle_MotionNotify(XEvent * ev) dy = scr->height - (m->next->y + m->next->h); dx = dx < 0 ? dx : 0; dy = dy < 0 ? dy : 0; + dx = m->x + dx < 0 ? -m->x : dx; + dy = m->y + dy < 0 ? -m->y : dy; if (dx || dy) feh_menu_slide_all_menus_relative(dx, dy); } -- cgit v1.2.3 From b359a39b1684455dd91781a8b49906d7eb18fb62 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 16 May 2018 22:36:06 +0200 Subject: properly escape image-bg argument in ~/.fehbg Closes #400 --- src/wallpaper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wallpaper.c b/src/wallpaper.c index 7cf2468..f1fb149 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -473,7 +473,7 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, fputs("tile", fp); if (opt.image_bg) { fputs(" --image-bg ", fp); - fputs(opt.image_bg, fp); + fputs(shell_escape(opt.image_bg), fp); } #ifdef HAVE_LIBXINERAMA if (opt.xinerama) { -- cgit v1.2.3 From f7ee0c34bcc2d2ae9075269c53d8b4c10c1594c5 Mon Sep 17 00:00:00 2001 From: Sebastian Bickerle Date: Sun, 10 Jun 2018 20:08:11 +0200 Subject: fix .fehbg output for --bg-max --- src/wallpaper.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/wallpaper.c b/src/wallpaper.c index f1fb149..db14a8c 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -467,8 +467,10 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, fputs("center", fp); else if (scaled) fputs("scale", fp); - else if (filled) + else if (filled == 1) fputs("fill", fp); + else if (filled == 2) + fputs("max", fp); else fputs("tile", fp); if (opt.image_bg) { -- cgit v1.2.3 From 91cecf5d3b32af133f7457eabb73fedc59bb2b39 Mon Sep 17 00:00:00 2001 From: giladogit <32686842+giladogit@users.noreply.github.com> Date: Fri, 6 Jul 2018 17:15:37 -0700 Subject: Update signals.h See issue #405 --- src/signals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/signals.h b/src/signals.h index 526285d..090ab0b 100644 --- a/src/signals.h +++ b/src/signals.h @@ -27,5 +27,5 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SIGNALS_H void setup_signal_handlers(); - +extern int sig_exit; #endif -- cgit v1.2.3 From 9bde3a460a24ae63fcd7bf68612ba0fc683786c6 Mon Sep 17 00:00:00 2001 From: giladogit <32686842+giladogit@users.noreply.github.com> Date: Fri, 6 Jul 2018 17:19:13 -0700 Subject: Update signals.c See issue #405 --- src/signals.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/signals.c b/src/signals.c index c08d5df..97192fa 100644 --- a/src/signals.c +++ b/src/signals.c @@ -33,6 +33,7 @@ void setup_signal_handlers() { struct sigaction feh_sh; sigset_t feh_ss; + sig_exit = 0; if ( (sigemptyset(&feh_ss) == -1) || (sigaddset(&feh_ss, SIGUSR1) == -1) || @@ -86,7 +87,7 @@ void feh_handle_signal(int signo) case SIGQUIT: if (childpid) killpg(childpid, SIGINT); - exit(128 + signo); + sig_exit = 128 + signo; } winwid = winwidget_get_first_window_of_type(WIN_TYPE_SLIDESHOW); -- cgit v1.2.3 From 6bc51aa57a2898817aeb92e616f221adf6881ab1 Mon Sep 17 00:00:00 2001 From: giladogit <32686842+giladogit@users.noreply.github.com> Date: Fri, 6 Jul 2018 17:21:03 -0700 Subject: Update main.c See issue #405 --- src/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index f1fca24..99397fd 100644 --- a/src/main.c +++ b/src/main.c @@ -87,7 +87,7 @@ int main(int argc, char **argv) /* main event loop */ while (feh_main_iteration(1)); - return(0); + return(sig_exit); } /* Return 0 to stop iterating, 1 if ok to continue. */ @@ -104,7 +104,7 @@ int feh_main_iteration(int block) double t1 = 0.0, t2 = 0.0; fehtimer ft; - if (window_num == 0) + if (window_num == 0 || sig_exit != 0) return(0); if (first) { @@ -137,7 +137,7 @@ int feh_main_iteration(int block) if (ev_handler[ev.type]) (*(ev_handler[ev.type])) (&ev); - if (window_num == 0) + if (window_num == 0 || sig_exit != 0) return(0); } XFlush(disp); @@ -208,7 +208,7 @@ int feh_main_iteration(int block) feh_event_handle_stdin(); } } - if (window_num == 0) + if (window_num == 0 || sig_exit != 0) return(0); return(1); -- cgit v1.2.3 From 00d45a4d00f45ed378ec5b1f5ae002ca918e58be Mon Sep 17 00:00:00 2001 From: giladogit <32686842+giladogit@users.noreply.github.com> Date: Sat, 7 Jul 2018 11:03:07 -0700 Subject: Update signals.c --- src/signals.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/signals.c b/src/signals.c index 97192fa..262423b 100644 --- a/src/signals.c +++ b/src/signals.c @@ -28,6 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "options.h" void feh_handle_signal(int); +int sig_exit; void setup_signal_handlers() { -- cgit v1.2.3 From 98f82337ac9da3faccf63d131818e7a77953ec2c Mon Sep 17 00:00:00 2001 From: ulteq Date: Tue, 17 Jul 2018 12:02:56 +0200 Subject: Improve screen clip feature --- src/winwidget.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/winwidget.c b/src/winwidget.c index e54b49e..fe0b505 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -799,12 +799,16 @@ void winwidget_resize(winwidget winwid, int w, int h, int force_resize) } if (winwid && ((winwid->w != w) || (winwid->h != h))) { if (opt.screen_clip) { - double required_zoom = 1.0; - int max_w = (w > scr_width) ? scr_width : w; - int max_h = (h > scr_height) ? scr_height : h; - feh_calc_needed_zoom(&required_zoom, winwid->im_w, winwid->im_h, max_w, max_h); - winwid->w = winwid->im_w * required_zoom; - winwid->h = winwid->im_h * required_zoom; + double required_zoom = winwid->zoom; + if (opt.scale_down && !opt.keep_zoom_vp) { + int max_w = (w > scr_width) ? scr_width : w; + int max_h = (h > scr_height) ? scr_height : h; + feh_calc_needed_zoom(&required_zoom, winwid->im_w, winwid->im_h, max_w, max_h); + } + int desired_w = winwid->im_w * required_zoom; + int desired_h = winwid->im_h * required_zoom; + winwid->w = (desired_w > scr_width) ? scr_width : desired_w; + winwid->h = (desired_h > scr_height) ? scr_height : desired_h; } if (winwid->full_screen) { XTranslateCoordinates(disp, winwid->win, attributes.root, -- cgit v1.2.3 From 171ebcfe02f87212fd8d2080bcc6217e5962955b Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Tue, 17 Jul 2018 17:29:35 +0200 Subject: signals.c: Globally initialize sig_exit; return immediately after SIGTERM etc --- src/signals.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/signals.c b/src/signals.c index 262423b..aeaf889 100644 --- a/src/signals.c +++ b/src/signals.c @@ -28,13 +28,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "options.h" void feh_handle_signal(int); -int sig_exit; +int sig_exit = 0; void setup_signal_handlers() { struct sigaction feh_sh; sigset_t feh_ss; - sig_exit = 0; if ( (sigemptyset(&feh_ss) == -1) || (sigaddset(&feh_ss, SIGUSR1) == -1) || @@ -89,6 +88,7 @@ void feh_handle_signal(int signo) if (childpid) killpg(childpid, SIGINT); sig_exit = 128 + signo; + return; } winwid = winwidget_get_first_window_of_type(WIN_TYPE_SLIDESHOW); -- cgit v1.2.3 From f428edbd1945e9464896fa65c795563ca346d47f Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Tue, 17 Jul 2018 17:30:11 +0200 Subject: feh_main_iteration: Properly check select() return value Trying to handle stdin when select() in fact returned an error due to being interrupted by a signal is a rather bad idea. --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index 99397fd..1a76e2d 100644 --- a/src/main.c +++ b/src/main.c @@ -191,7 +191,7 @@ int feh_main_iteration(int block) in that */ feh_handle_timer(); } - else if (count && (FD_ISSET(0, &fdset))) + else if ((count > 0) && (FD_ISSET(0, &fdset))) feh_event_handle_stdin(); } } else { @@ -204,7 +204,7 @@ int feh_main_iteration(int block) && ((errno == ENOMEM) || (errno == EINVAL) || (errno == EBADF))) eprintf("Connection to X display lost"); - else if (count && (FD_ISSET(0, &fdset))) + else if ((count > 0) && (FD_ISSET(0, &fdset))) feh_event_handle_stdin(); } } -- cgit v1.2.3 From 9f65dacdcf4e01ddf7becea9fc57072bdbd5c175 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Fri, 20 Jul 2018 05:44:57 +0200 Subject: Blame Imlib2 when failing to create > 32000x32000 px image --- src/index.c | 13 ++++++++++--- src/thumbnail.c | 13 ++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/index.c b/src/index.c index ca1664b..af3adea 100644 --- a/src/index.c +++ b/src/index.c @@ -147,9 +147,16 @@ void init_index_mode(void) index_image_height = h + title_area_h; im_main = imlib_create_image(index_image_width, index_image_height); - if (!im_main) - eprintf("Failed to create %dx%d pixels (%d MB) index image. Do you have enough RAM?", - index_image_width, index_image_height, index_image_width * index_image_height * 4 / (1024*1024)); + if (!im_main) { + if (index_image_height >= 32768 || index_image_width >= 32768) { + eprintf("Failed to create %dx%d pixels (%d MB) index image.\n" + "This is probably due to Imlib2 issues when dealing with images larger than 32k x 32k pixels.", + index_image_width, index_image_height, index_image_width * index_image_height * 4 / (1024*1024)); + } else { + eprintf("Failed to create %dx%d pixels (%d MB) index image. Do you have enough RAM?", + index_image_width, index_image_height, index_image_width * index_image_height * 4 / (1024*1024)); + } + } if (bg_im) gib_imlib_blend_image_onto_image(im_main, bg_im, diff --git a/src/thumbnail.c b/src/thumbnail.c index cf38cfc..45fbabe 100644 --- a/src/thumbnail.c +++ b/src/thumbnail.c @@ -149,9 +149,16 @@ void init_thumbnail_mode(void) D(("imlib_create_image(%d, %d)\n", index_image_width, index_image_height)); td.im_main = imlib_create_image(index_image_width, index_image_height); - if (!td.im_main) - eprintf("Failed to create %dx%d pixels (%d MB) index image. Do you have enough RAM?", - index_image_width, index_image_height, index_image_width * index_image_height * 4 / (1024*1024)); + if (!td.im_main) { + if (index_image_height >= 32768 || index_image_width >= 32768) { + eprintf("Failed to create %dx%d pixels (%d MB) index image.\n" + "This is probably due to Imlib2 issues when dealing with images larger than 32k x 32k pixels.", + index_image_width, index_image_height, index_image_width * index_image_height * 4 / (1024*1024)); + } else { + eprintf("Failed to create %dx%d pixels (%d MB) index image. Do you have enough RAM?", + index_image_width, index_image_height, index_image_width * index_image_height * 4 / (1024*1024)); + } + } gib_imlib_image_set_has_alpha(td.im_main, 1); -- cgit v1.2.3 From 607374d4c7f7a133d3d1c5c012a6a5af9e2e60bf Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sun, 5 Aug 2018 13:57:45 +0200 Subject: Merge --dcraw-timeout and --magick-timeout into --conversion-timeout --- src/filelist.c | 8 ++++---- src/imlib.c | 10 +++++----- src/options.c | 10 +++++----- src/options.h | 3 +-- 4 files changed, 15 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/filelist.c b/src/filelist.c index eb8e294..b492965 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -574,7 +574,7 @@ gib_list *feh_read_filelist(char *filename) Imlib_Load_Error err = IMLIB_LOAD_ERROR_NONE; Imlib_Image tmp_im; struct stat st; - signed short tmp_magick_timeout; + signed short tmp_conversion_timeout; if (!filename) return(NULL); @@ -582,8 +582,8 @@ gib_list *feh_read_filelist(char *filename) /* * feh_load_image will fail horribly if filename is not seekable */ - tmp_magick_timeout = opt.magick_timeout; - opt.magick_timeout = -1; + tmp_conversion_timeout = opt.conversion_timeout; + opt.conversion_timeout = -1; if (!stat(filename, &st) && S_ISREG(st.st_mode)) { tmp_im = imlib_load_image_with_error_return(filename, &err); if (err == IMLIB_LOAD_ERROR_NONE) { @@ -594,7 +594,7 @@ gib_list *feh_read_filelist(char *filename) return NULL; } } - opt.magick_timeout = tmp_magick_timeout; + opt.conversion_timeout = tmp_conversion_timeout; errno = 0; diff --git a/src/imlib.c b/src/imlib.c index 2d1b47a..f41cdcd 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -230,7 +230,7 @@ int feh_load_image(Imlib_Image * im, feh_file * file) if ((tmpname = feh_http_load_image(file->filename)) == NULL) err = IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST; } - else if (opt.dcraw_timeout >= 0 && feh_file_is_raw(file->filename)) { + else if (opt.conversion_timeout >= 0 && feh_file_is_raw(file->filename)) { image_source = SRC_DCRAW; tmpname = feh_dcraw_load_image(file->filename); if (!tmpname) @@ -239,7 +239,7 @@ int feh_load_image(Imlib_Image * im, feh_file * file) else *im = imlib_load_image_with_error_return(file->filename, &err); - if (opt.magick_timeout >= 0 && ( + if (opt.conversion_timeout >= 0 && ( (err == IMLIB_LOAD_ERROR_UNKNOWN) || (err == IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT))) { image_source = SRC_MAGICK; @@ -377,7 +377,7 @@ static char *feh_dcraw_load_image(char *filename) dup(fd); close(fd); - alarm(opt.dcraw_timeout); + alarm(opt.conversion_timeout); execlp("dcraw", "dcraw", "-c", "-e", filename, NULL); _exit(1); } @@ -481,10 +481,10 @@ static char *feh_magick_load_image(char *filename) _exit(1); } else { - alarm(opt.magick_timeout); + alarm(opt.conversion_timeout); waitpid(childpid, &status, 0); kill(childpid, SIGKILL); - if (opt.magick_timeout > 0 && !alarm(0)) { + if (opt.conversion_timeout > 0 && !alarm(0)) { unlink(sfn); free(sfn); sfn = NULL; diff --git a/src/options.c b/src/options.c index b0d67cd..af0f07d 100644 --- a/src/options.c +++ b/src/options.c @@ -55,8 +55,7 @@ void init_parse_options(int argc, char **argv) opt.display = 1; opt.aspect = 1; opt.slideshow_delay = 0.0; - opt.dcraw_timeout = -1; - opt.magick_timeout = -1; + opt.conversion_timeout = -1; opt.thumb_w = 60; opt.thumb_h = 60; opt.thumb_redraw = 10; @@ -416,7 +415,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"insecure" , 0, 0, 240}, {"no-recursive" , 0, 0, 241}, {"cache-size" , 1, 0, 243}, - {"dcraw-timeout" , 1, 0, 245}, + {"conversion-timeout" , 1, 0, 245}, {"version-sort" , 0, 0, 246}, {"offset" , 1, 0, 247}, {0, 0, 0, 0} @@ -695,7 +694,8 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) opt.index_info = estrdup(optarg); break; case 208: - opt.magick_timeout = atoi(optarg); + weprintf("--magick-timeout is deprecated, please use --conversion-timeout instead"); + opt.conversion_timeout = atoi(optarg); break; case 209: opt.actions[1] = estrdup(optarg); @@ -786,7 +786,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) opt.cache_size = 2048; break; case 245: - opt.dcraw_timeout = atoi(optarg); + opt.conversion_timeout = atoi(optarg); break; case 246: opt.version_sort = 1; diff --git a/src/options.h b/src/options.h index 741b0c7..936b4bd 100644 --- a/src/options.h +++ b/src/options.h @@ -133,8 +133,7 @@ struct __fehoptions { double slideshow_delay; - signed short dcraw_timeout; - signed short magick_timeout; + signed int conversion_timeout; Imlib_Font menu_fn; }; -- cgit v1.2.3 From 5c28573eb939ef9e18b993db67c78c35f748151f Mon Sep 17 00:00:00 2001 From: ulteq Date: Sat, 18 Aug 2018 14:34:47 +0200 Subject: Prevent the premature abort of the automatic-slideshow if only one image is there Fixes: #415 --- src/slideshow.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/slideshow.c b/src/slideshow.c index b27a7e8..e87d1b9 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -222,6 +222,9 @@ void slideshow_change_image(winwidget winwid, int change, int render) */ int our_filelist_len = filelist_len; + if (opt.slideshow_delay > 0.0) + feh_add_timer(cb_slide_timer, winwid, opt.slideshow_delay, "SLIDE_CHANGE"); + /* Without this, clicking a one-image slideshow reloads it. Not very * intelligent behaviour :-) */ if (filelist_len < 2 && opt.cycle_once == 0) @@ -359,8 +362,6 @@ void slideshow_change_image(winwidget winwid, int change, int render) if (filelist_len == 0) eprintf("No more slides in show"); - if (opt.slideshow_delay > 0.0) - feh_add_timer(cb_slide_timer, winwid, opt.slideshow_delay, "SLIDE_CHANGE"); return; } -- cgit v1.2.3 From 935f5c340f0e31351c9fb53997c746ec30f435f1 Mon Sep 17 00:00:00 2001 From: ulteq Date: Sun, 19 Aug 2018 14:47:11 +0200 Subject: Antialias rotated images even at native resolution Partial fix of: #310 --- src/winwidget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/winwidget.c b/src/winwidget.c index fe0b505..b68d56f 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -520,7 +520,7 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) D(("sx: %d sy: %d sw: %d sh: %d dx: %d dy: %d dw: %d dh: %d zoom: %f\n", sx, sy, sw, sh, dx, dy, dw, dh, winwid->zoom)); - if ((winwid->zoom != 1.0) && !force_alias && !winwid->force_aliasing) + if ((winwid->zoom != 1.0 || winwid->has_rotated) && !force_alias && !winwid->force_aliasing) antialias = 1; D(("winwidget_render(): winwid->im_angle = %f\n", winwid->im_angle)); -- cgit v1.2.3 From f3ea5c887e034f08d2735c7a32876f94ee9ef60a Mon Sep 17 00:00:00 2001 From: ulteq Date: Mon, 1 Jan 2018 15:37:32 +0100 Subject: Add --no-cycle option Closes: #124 --- src/help.raw | 1 + src/options.c | 4 ++++ src/options.h | 1 + src/slideshow.c | 7 +++++++ 4 files changed, 13 insertions(+) (limited to 'src') diff --git a/src/help.raw b/src/help.raw index 86bb617..52d06bf 100644 --- a/src/help.raw +++ b/src/help.raw @@ -38,6 +38,7 @@ OPTIONS --auto-rotate Rotate images according to Exif info (if compiled with exif=1) -^, --title TITLE Set window title (see FORMAT SPECIFIERS) -D, --slideshow-delay NUM Set delay between automatically changing slides + --no-cycle Stop at both ends of the filelist --cycle-once Exit after one loop through the slideshow -R, --reload NUM Reload images after NUM seconds -k, --keep-http Keep local copies when viewing HTTP/FTP files diff --git a/src/options.c b/src/options.c index af0f07d..1a47a39 100644 --- a/src/options.c +++ b/src/options.c @@ -415,6 +415,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"insecure" , 0, 0, 240}, {"no-recursive" , 0, 0, 241}, {"cache-size" , 1, 0, 243}, + {"no-cycle" , 0, 0, 244}, {"conversion-timeout" , 1, 0, 245}, {"version-sort" , 0, 0, 246}, {"offset" , 1, 0, 247}, @@ -785,6 +786,9 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) if (opt.cache_size > 2048) opt.cache_size = 2048; break; + case 244: + opt.no_cycle = 1; + break; case 245: opt.conversion_timeout = atoi(optarg); break; diff --git a/src/options.h b/src/options.h index 936b4bd..122d39e 100644 --- a/src/options.h +++ b/src/options.h @@ -69,6 +69,7 @@ struct __fehoptions { unsigned char draw_info; unsigned char cache_thumbnails; unsigned char cycle_once; + unsigned char no_cycle; unsigned char hold_actions[10]; unsigned char text_bg; unsigned char no_fehbg; diff --git a/src/slideshow.c b/src/slideshow.c index b27a7e8..77f5a82 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -215,6 +215,7 @@ void feh_reload_image(winwidget w, int resize, int force_new) void slideshow_change_image(winwidget winwid, int change, int render) { gib_list *last = NULL; + gib_list *previous_file = current_file; int i = 0; int jmp = 1; /* We can't use filelist_len in the for loop, since that changes when we @@ -332,6 +333,12 @@ void slideshow_change_image(winwidget winwid, int change, int render) last = NULL; } + if (opt.no_cycle && + ((current_file == filelist && change == SLIDE_NEXT) || + (previous_file == filelist && change == SLIDE_PREV))) { + current_file = previous_file; + } + if (winwidget_loadimage(winwid, FEH_FILE(current_file->data))) { int w = gib_imlib_image_get_width(winwid->im); int h = gib_imlib_image_get_height(winwid->im); -- cgit v1.2.3 From dbc8dc8ceabdab55c5c8c74708af7788ade1c151 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sat, 18 Aug 2018 19:43:32 +0200 Subject: combine --no-cycle and --cycle-once into --on-last-slide={quit,hold} --- src/help.raw | 4 ++-- src/options.c | 16 +++++++++++++--- src/options.h | 9 +++++++-- src/slideshow.c | 10 +++++----- 4 files changed, 27 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/help.raw b/src/help.raw index 52d06bf..ebffae3 100644 --- a/src/help.raw +++ b/src/help.raw @@ -38,8 +38,8 @@ OPTIONS --auto-rotate Rotate images according to Exif info (if compiled with exif=1) -^, --title TITLE Set window title (see FORMAT SPECIFIERS) -D, --slideshow-delay NUM Set delay between automatically changing slides - --no-cycle Stop at both ends of the filelist - --cycle-once Exit after one loop through the slideshow + --on-last-slide quit Exit after one loop through the slide show + --on-last-slide hold Stop at both ends of the filelist -R, --reload NUM Reload images after NUM seconds -k, --keep-http Keep local copies when viewing HTTP/FTP files --insecure Disable peer/host verification when using HTTPS. diff --git a/src/options.c b/src/options.c index 1a47a39..38d2568 100644 --- a/src/options.c +++ b/src/options.c @@ -415,7 +415,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"insecure" , 0, 0, 240}, {"no-recursive" , 0, 0, 241}, {"cache-size" , 1, 0, 243}, - {"no-cycle" , 0, 0, 244}, + {"on-last-slide" , 1, 0, 244}, {"conversion-timeout" , 1, 0, 245}, {"version-sort" , 0, 0, 246}, {"offset" , 1, 0, 247}, @@ -743,7 +743,8 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) break; #endif case 224: - opt.cycle_once = 1; + weprintf("--cycle-once is deprecated, please use --on-last-slide=quit instead"); + opt.on_last_slide = ON_LAST_SLIDE_QUIT; break; case 225: opt.xinerama = 0; @@ -787,7 +788,16 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) opt.cache_size = 2048; break; case 244: - opt.no_cycle = 1; + if (!strcmp(optarg, "quit")) { + opt.on_last_slide = ON_LAST_SLIDE_QUIT; + } else if (!strcmp(optarg, "hold")) { + opt.on_last_slide = ON_LAST_SLIDE_HOLD; + } else if (!strcmp(optarg, "resume")) { + opt.on_last_slide = ON_LAST_SLIDE_RESUME; + } else { + weprintf("Unrecognized on-last-slide action \"%s\"." + "Supported actions: hold, resume, quit\n", optarg); + } break; case 245: opt.conversion_timeout = atoi(optarg); diff --git a/src/options.h b/src/options.h index 122d39e..606b8e6 100644 --- a/src/options.h +++ b/src/options.h @@ -27,6 +27,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef OPTIONS_H #define OPTIONS_H +enum on_last_slide_action { + ON_LAST_SLIDE_RESUME = 0, + ON_LAST_SLIDE_QUIT, + ON_LAST_SLIDE_HOLD +}; + struct __fehoptions { unsigned char multiwindow; unsigned char montage; @@ -68,8 +74,7 @@ struct __fehoptions { unsigned char draw_actions; unsigned char draw_info; unsigned char cache_thumbnails; - unsigned char cycle_once; - unsigned char no_cycle; + unsigned char on_last_slide; unsigned char hold_actions[10]; unsigned char text_bg; unsigned char no_fehbg; diff --git a/src/slideshow.c b/src/slideshow.c index 77f5a82..6f622b4 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -225,7 +225,7 @@ void slideshow_change_image(winwidget winwid, int change, int render) /* Without this, clicking a one-image slideshow reloads it. Not very * intelligent behaviour :-) */ - if (filelist_len < 2 && opt.cycle_once == 0) + if (filelist_len < 2 && opt.on_last_slide != ON_LAST_SLIDE_QUIT) return; /* Ok. I do this in such an odd way to ensure that if the last or first * @@ -333,7 +333,7 @@ void slideshow_change_image(winwidget winwid, int change, int render) last = NULL; } - if (opt.no_cycle && + if (opt.on_last_slide == ON_LAST_SLIDE_HOLD && ((current_file == filelist && change == SLIDE_NEXT) || (previous_file == filelist && change == SLIDE_PREV))) { current_file = previous_file; @@ -574,10 +574,10 @@ void feh_filelist_image_remove(winwidget winwid, char do_delete) doomed = current_file; /* - * work around feh_list_jump exiting if cycle_once is enabled + * work around feh_list_jump exiting if ON_LAST_SLIDE_QUIT is set * and no further files are left (we need to delete first) */ - if (opt.cycle_once && ! doomed->next && do_delete) { + if (opt.on_last_slide == ON_LAST_SLIDE_QUIT && ! doomed->next && do_delete) { feh_file_rm_and_free(filelist, doomed); exit(0); } @@ -653,7 +653,7 @@ gib_list *feh_list_jump(gib_list * root, gib_list * l, int direction, int num) if (ret->next) { ret = ret->next; } else { - if (opt.cycle_once) { + if (opt.on_last_slide == ON_LAST_SLIDE_QUIT) { exit(0); } if (opt.randomize) { -- cgit v1.2.3 From 5f46d5a4c29936826e5355e684056b2e8423921f Mon Sep 17 00:00:00 2001 From: ulteq Date: Wed, 29 Aug 2018 20:32:07 +0200 Subject: This will fix 'jump_last' and 'jump_first' when using no-cycle --- src/slideshow.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/slideshow.c b/src/slideshow.c index 6a4f4d1..3770677 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -238,9 +238,11 @@ void slideshow_change_image(winwidget winwid, int change, int render) if (change == SLIDE_FIRST) { current_file = gib_list_last(filelist); change = SLIDE_NEXT; + previous_file = NULL; } else if (change == SLIDE_LAST) { current_file = filelist; change = SLIDE_PREV; + previous_file = NULL; } /* The for loop prevents us looping infinitely */ @@ -336,7 +338,7 @@ void slideshow_change_image(winwidget winwid, int change, int render) last = NULL; } - if (opt.on_last_slide == ON_LAST_SLIDE_HOLD && + if (opt.on_last_slide == ON_LAST_SLIDE_HOLD && previous_file && ((current_file == filelist && change == SLIDE_NEXT) || (previous_file == filelist && change == SLIDE_PREV))) { current_file = previous_file; -- cgit v1.2.3