diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/collage.c | 2 | ||||
-rw-r--r-- | src/debug.h | 2 | ||||
-rw-r--r-- | src/events.c | 6 | ||||
-rw-r--r-- | src/feh.h | 2 | ||||
-rw-r--r-- | src/filelist.c | 4 | ||||
-rw-r--r-- | src/gib_list.c | 1 | ||||
-rw-r--r-- | src/imlib.c | 56 | ||||
-rw-r--r-- | src/index.c | 15 | ||||
-rw-r--r-- | src/index.h | 2 | ||||
-rw-r--r-- | src/keyevents.c | 29 | ||||
-rw-r--r-- | src/list.c | 2 | ||||
-rw-r--r-- | src/main.c | 16 | ||||
-rw-r--r-- | src/menu.c | 2 | ||||
-rw-r--r-- | src/menu.h | 2 | ||||
-rw-r--r-- | src/options.c | 8 | ||||
-rw-r--r-- | src/options.h | 6 | ||||
-rw-r--r-- | src/signals.c | 6 | ||||
-rw-r--r-- | src/signals.h | 2 | ||||
-rw-r--r-- | src/slideshow.c | 61 | ||||
-rw-r--r-- | src/structs.h | 2 | ||||
-rw-r--r-- | src/thumbnail.c | 30 | ||||
-rw-r--r-- | src/thumbnail.h | 2 | ||||
-rw-r--r-- | src/timers.c | 2 | ||||
-rw-r--r-- | src/wallpaper.c | 75 | ||||
-rw-r--r-- | src/wallpaper.h | 2 | ||||
-rw-r--r-- | src/winwidget.c | 205 | ||||
-rw-r--r-- | src/winwidget.h | 3 |
27 files changed, 292 insertions, 253 deletions
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..89eaab8 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 @@ -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); } @@ -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 453f795..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 @@ -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)); 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 b6041fc..2d1b47a 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 @@ -135,9 +135,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; } @@ -404,8 +401,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; basename = strrchr(filename, '/'); @@ -436,6 +435,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); @@ -457,6 +472,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); } @@ -470,13 +490,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; } diff --git a/src/index.c b/src/index.c index c8c34c5..af3adea 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 @@ -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/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 793767b..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 @@ -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) @@ -774,6 +798,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; } @@ -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 @@ -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 @@ -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); @@ -85,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. */ @@ -102,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) { @@ -135,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); @@ -189,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 { @@ -202,11 +204,11 @@ 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(); } } - if (window_num == 0) + if (window_num == 0 || sig_exit != 0) return(0); return(1); @@ -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 @@ -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 29ce836..b0d67cd 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 @@ -418,6 +418,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"cache-size" , 1, 0, 243}, {"dcraw-timeout" , 1, 0, 245}, {"version-sort" , 0, 0, 246}, + {"offset" , 1, 0, 247}, {0, 0, 0, 0} }; int optch = 0, cmdx = 0; @@ -593,6 +594,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; @@ -789,6 +791,10 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) case 246: opt.version_sort = 1; break; + case 247: + 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 88121e6..741b0c7 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 @@ -106,11 +106,15 @@ struct __fehoptions { int sort; int version_sort; int debug; + int geom_enabled; int geom_flags; int geom_x; int geom_y; unsigned int geom_w; unsigned int 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/signals.c b/src/signals.c index 8a3a8f7..aeaf889 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 @@ -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 = 0; void setup_signal_handlers() { @@ -86,7 +87,8 @@ void feh_handle_signal(int signo) case SIGQUIT: if (childpid) killpg(childpid, SIGINT); - exit(128 + signo); + sig_exit = 128 + signo; + return; } winwid = winwidget_get_first_window_of_type(WIN_TYPE_SLIDESHOW); 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 diff --git a/src/slideshow.c b/src/slideshow.c index effdcaf..b27a7e8 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 @@ -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,16 +207,7 @@ 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, 0, 0); - } else { - winwidget_render_image(w, resize, 0); - } + winwidget_render_image(w, resize, 0); return; } @@ -241,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) @@ -356,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); @@ -378,19 +346,8 @@ 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) { - 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 @@ -468,6 +425,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 +527,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; 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 003c7b4..45fbabe 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 @@ -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); @@ -766,17 +773,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/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 2d3d3bc..db14a8c 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 @@ -453,36 +453,69 @@ 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); } 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 == 1) + fputs("fill", fp); + else if (filled == 2) + fputs("max", fp); + else + fputs("tile", fp); + if (opt.image_bg) { + fputs(" --image-bg ", fp); + fputs(shell_escape(opt.image_bg), 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++) { - fputs(shell_escape(cmdargv[i]), fp); - fputc(' ', 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); + 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); + absolute_path = feh_absolute_path(fil); + fputs(shell_escape(absolute_path), fp); + free(absolute_path); } fputc('\n', fp); fclose(fp); 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 bb6181a..fe0b505 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 @@ -323,11 +323,12 @@ 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; } + return; } @@ -422,138 +423,65 @@ 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); 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)); - 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->zoom != 1.0) - || (winwid->w > winwid->im_w || winwid->h > winwid->im_h) - || (winwid->has_rotated))) - feh_draw_checks(winwid); + /* winwidget_setup_pixmaps(winwid) resets the winwid->had_resize flag */ + int had_resize = winwid->had_resize || resize; - 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); + winwidget_setup_pixmaps(winwid); - /* - * 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); + 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); + winwid->zoom = opt.default_zoom ? (0.01 * opt.default_zoom) : 1.0; - 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 ((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 (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; + 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; } -#endif /* HAVE_LIBXINERAMA */ } else { - if (opt.geom_flags & WidthValue) { - max_w = opt.geom_w; - } - if (opt.geom_flags & HeightValue) { - max_h = opt.geom_h; - } + winwid->im_x = (int) (winwid->w - (winwid->im_w * winwid->zoom)) >> 1; } - - 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 <jens.laas@data.slu.se> - * 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; + if (opt.offset_flags & YValue) { + if (opt.offset_flags & YNegative) { + winwid->im_y = winwid->h - (winwid->im_h * winwid->zoom) - opt.offset_y; } 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; - } + winwid->im_y = - opt.offset_y * winwid->zoom; } } 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; + winwid->im_y = (int) (winwid->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; - } + + winwid->had_resize = 0; + + 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; @@ -706,13 +634,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; @@ -747,8 +668,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); @@ -874,24 +793,30 @@ 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))) { - /* 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 = 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, - -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); @@ -1019,10 +944,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; diff --git a/src/winwidget.h b/src/winwidget.h index dd8489a..0a707ac 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 @@ -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); |