From c61a0a90db45099b3a572979774eba8dd0e82819 Mon Sep 17 00:00:00 2001 From: "Dmitrij D. Czarkoff" Date: Wed, 30 Dec 2015 15:48:03 +0100 Subject: Allow fractional slideshow timeout Accept slideshow timeout expressed as fractional numbers. It is intentionally lax, so that arguments like ".1" or "5." are accepted and give no surprises. --- doc/imv.1 | 1 + src/main.c | 61 ++++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/doc/imv.1 b/doc/imv.1 index d328295..cbd5c68 100644 --- a/doc/imv.1 +++ b/doc/imv.1 @@ -61,6 +61,7 @@ may be expressed as a number or as a path of an image. Recursively search input paths for files. .It Fl t Ar seconds Set the slideshow delay in seconds. +Fractional numbers are accepted. Setting this to zero disables slideshow mode, which is the default. .It Fl u Use nearest neighbour resampling. Recommended for pixel art. diff --git a/src/main.c b/src/main.c index 9a25dfb..5e78017 100644 --- a/src/main.c +++ b/src/main.c @@ -37,7 +37,7 @@ struct { int nearest_neighbour; int solid_bg; int list; - unsigned int delay; + unsigned long delay; unsigned char bg_r; unsigned char bg_g; unsigned char bg_b; @@ -129,7 +129,7 @@ static void parse_args(int argc, char** argv) opterr = 0; const char* name = argv[0]; - char o; + char *argp, o; while((o = getopt(argc, argv, "firaudhln:b:e:t:")) != -1) { switch(o) { @@ -163,7 +163,24 @@ static void parse_args(int argc, char** argv) g_options.font = optarg; break; case 't': - g_options.delay = (unsigned int)atoi(optarg); + g_options.delay = strtoul(optarg, &argp, 10); + g_options.delay *= 1000; + if (*argp == '.') { + char *ep; + long delay = strtoul(++argp, &ep, 10); + for (int i = 3 - (ep - argp); i; i--) { + delay *= 10; + } + if (delay < 1000) { + g_options.delay += delay; + } else { + g_options.delay = ULONG_MAX; + } + } + if (g_options.delay == ULONG_MAX) { + fprintf(stderr, "Wrong slideshow delay '%s'. Aborting.\n", optarg); + exit(1); + } break; case '?': fprintf(stderr, "Unknown argument '%c'. Aborting.\n", optopt); @@ -297,8 +314,7 @@ int main(int argc, char** argv) int need_redraw = 1; /* used to calculate when to skip to the next image in slideshow mode */ - unsigned int msecs_passed = 0; - unsigned int delay_seconds_passed = 0; + unsigned long delay_mseconds_passed = 0; int quit = 0; while(!quit) { @@ -319,13 +335,13 @@ int main(int argc, char** argv) case SDLK_LEFT: imv_navigator_select_rel(&nav, -1); /* reset slideshow delay */ - delay_seconds_passed = 0; + delay_mseconds_passed = 0; break; case SDLK_RIGHTBRACKET: case SDLK_RIGHT: imv_navigator_select_rel(&nav, 1); /* reset slideshow delay */ - delay_seconds_passed = 0; + delay_mseconds_passed = 0; break; case SDLK_EQUALS: case SDLK_i: @@ -463,16 +479,11 @@ int main(int argc, char** argv) if (g_options.delay) { unsigned int dt = current_time - last_time; - msecs_passed = msecs_passed + dt; - /* tick every second */ - if(msecs_passed >= 1000) { - msecs_passed = 0; - delay_seconds_passed++; - need_redraw = 1; - if(delay_seconds_passed >= g_options.delay) { - imv_navigator_select_rel(&nav, 1); - delay_seconds_passed = 0; - } + delay_mseconds_passed += dt; + need_redraw = 1; + if(delay_mseconds_passed >= g_options.delay) { + imv_navigator_select_rel(&nav, 1); + delay_mseconds_passed = 0; } } @@ -488,10 +499,10 @@ int main(int argc, char** argv) /* update window title */ const char *current_path = imv_navigator_selection(&nav); char title[256]; - if(g_options.delay) { - snprintf(&title[0], sizeof(title), "imv - [%i/%i] [%i/%is] [%ix%i] %s", - nav.cur_path + 1, nav.num_paths, delay_seconds_passed + 1, - g_options.delay, tex.width, tex.height, current_path); + if(g_options.delay > 1000) { + snprintf(&title[0], sizeof(title), "imv - [%i/%i] [%lu/%lus] [%ix%i] %s", + nav.cur_path + 1, nav.num_paths, delay_mseconds_passed / 1000 + 1, + g_options.delay / 1000, tex.width, tex.height, current_path); } else { snprintf(&title[0], sizeof(title), "imv - [%i/%i] [%ix%i] %s", nav.cur_path + 1, nav.num_paths, @@ -501,10 +512,10 @@ int main(int argc, char** argv) /* update the overlay */ if(font) { - if(g_options.delay) { - snprintf(&title[0], sizeof(title), "[%i/%i] [%i/%is] %s", - nav.cur_path + 1, nav.num_paths, delay_seconds_passed + 1, - g_options.delay, current_path); + if(g_options.delay > 1000) { + snprintf(&title[0], sizeof(title), "[%i/%i] [%lu/%lus] %s", + nav.cur_path + 1, nav.num_paths, delay_mseconds_passed / 1000 + 1, + g_options.delay / 1000, current_path); } else { snprintf(&title[0], sizeof(title), "[%i/%i] %s", nav.cur_path + 1, nav.num_paths, current_path); -- cgit v1.2.3 From 1ca3d027dee0c693265a2d4519ee6c7ebef6fd1c Mon Sep 17 00:00:00 2001 From: "Dmitrij D. Czarkoff" Date: Wed, 30 Dec 2015 17:44:48 +0100 Subject: Reduce amount of stat(2) calls Add 8-bit variable that is passed to imv_navigator_poll_changed(). Decrement it on each run of main loop. When it gets to 0, call stat(2). --- src/main.c | 11 +++++++++-- src/navigator.c | 13 ++++++++----- src/navigator.h | 2 +- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/main.c b/src/main.c index 5e78017..6150558 100644 --- a/src/main.c +++ b/src/main.c @@ -17,6 +17,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include +#include #include #include #include @@ -310,6 +311,9 @@ int main(int argc, char** argv) unsigned int last_time; unsigned int current_time; + /* keep file change polling rate under control */ + static uint8_t poll_countdown = UINT8_MAX; + /* do we need to redraw the window? */ int need_redraw = 1; @@ -434,7 +438,7 @@ int main(int argc, char** argv) } /* if the user has changed image, start loading the new one */ - if(imv_navigator_poll_changed(&nav)) { + if(imv_navigator_poll_changed(&nav, poll_countdown--)) { const char *current_path = imv_navigator_selection(&nav); if(!current_path) { fprintf(stderr, "No input files left. Exiting.\n"); @@ -476,7 +480,7 @@ int main(int argc, char** argv) } /* handle slideshow */ - if (g_options.delay) { + if(g_options.delay) { unsigned int dt = current_time - last_time; delay_mseconds_passed += dt; @@ -560,6 +564,9 @@ int main(int argc, char** argv) /* redraw complete, unset the flag */ need_redraw = 0; + /* reset poll countdown timer */ + poll_countdown = UINT8_MAX; + /* tell SDL to show the newly drawn frame */ SDL_RenderPresent(renderer); } diff --git a/src/navigator.c b/src/navigator.c index c504cd8..fb2a3cd 100644 --- a/src/navigator.c +++ b/src/navigator.c @@ -210,19 +210,22 @@ int imv_navigator_find_path(struct imv_navigator *nav, const char *path) return -1; } -int imv_navigator_poll_changed(struct imv_navigator *nav) +int imv_navigator_poll_changed(struct imv_navigator *nav, const int nopoll) { if(nav->changed) { nav->changed = 0; return 1; - } else { + } + + if(!nopoll) { struct stat file_info; - if (stat(nav->paths[nav->cur_path], &file_info) == -1) + if(stat(nav->paths[nav->cur_path], &file_info) == -1) { return 0; - if (nav->mtimes[nav->cur_path] != file_info.st_mtim.tv_sec) { + } + if(nav->mtimes[nav->cur_path] != file_info.st_mtim.tv_sec) { nav->mtimes[nav->cur_path] = file_info.st_mtim.tv_sec; return 1; } - return 0; } + return 0; } diff --git a/src/navigator.h b/src/navigator.h index 4fd2fa7..749f656 100644 --- a/src/navigator.h +++ b/src/navigator.h @@ -62,6 +62,6 @@ int imv_navigator_find_path(struct imv_navigator *nav, const char *path); /* Returns 1 if either the currently selected path or underlying file has * changed since last called */ -int imv_navigator_poll_changed(struct imv_navigator *nav); +int imv_navigator_poll_changed(struct imv_navigator *nav, const int nopoll); #endif -- cgit v1.2.3 From 47b702afc83f91c433fe35e48a48f7aee45ef3b5 Mon Sep 17 00:00:00 2001 From: "Dmitrij D. Czarkoff" Date: Fri, 1 Jan 2016 12:28:14 +0100 Subject: Include --- src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.c b/src/main.c index 6150558..25ffce1 100644 --- a/src/main.c +++ b/src/main.c @@ -15,6 +15,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include #include #include #include -- cgit v1.2.3