@@ -126,7 +126,7 @@ bool cg_reload_image(arg_t a) | |||||
load_image(fileidx); | load_image(fileidx); | ||||
} else { | } else { | ||||
win_set_cursor(&win, CURSOR_WATCH); | win_set_cursor(&win, CURSOR_WATCH); | ||||
if (!tns_load(&tns, fileidx, true)) { | |||||
if (!tns_load(&tns, fileidx, true, false)) { | |||||
remove_file(fileidx, false); | remove_file(fileidx, false); | ||||
tns.dirty = true; | tns.dirty = true; | ||||
} | } | ||||
@@ -385,7 +385,10 @@ void update_info(void) | |||||
r->p = r->buf; | r->p = r->buf; | ||||
if (mode == MODE_THUMB) { | if (mode == MODE_THUMB) { | ||||
if (tns.loadnext < tns.end) { | if (tns.loadnext < tns.end) { | ||||
bar_put(l, "Loading... %0*d", fw, MAX(tns.loadnext, 1)); | |||||
bar_put(l, "Loading... %0*d", fw, tns.loadnext + 1); | |||||
ow_info = false; | |||||
} else if (tns.initnext < filecnt) { | |||||
bar_put(l, "Caching... %0*d", fw, tns.initnext + 1); | |||||
ow_info = false; | ow_info = false; | ||||
} else { | } else { | ||||
ow_info = true; | ow_info = true; | ||||
@@ -453,7 +456,7 @@ void reset_cursor(void) | |||||
} | } | ||||
} | } | ||||
} else { | } else { | ||||
if (tns.loadnext < tns.end) | |||||
if (tns.loadnext < tns.end || tns.initnext < filecnt) | |||||
cursor = CURSOR_WATCH; | cursor = CURSOR_WATCH; | ||||
else | else | ||||
cursor = CURSOR_ARROW; | cursor = CURSOR_ARROW; | ||||
@@ -694,26 +697,29 @@ void run(void) | |||||
int xfd; | int xfd; | ||||
fd_set fds; | fd_set fds; | ||||
struct timeval timeout; | struct timeval timeout; | ||||
bool discard, load_thumb, to_set; | |||||
bool discard, init_thumb, load_thumb, to_set; | |||||
XEvent ev, nextev; | XEvent ev, nextev; | ||||
while (true) { | while (true) { | ||||
to_set = check_timeouts(&timeout); | to_set = check_timeouts(&timeout); | ||||
init_thumb = mode == MODE_THUMB && tns.initnext < filecnt; | |||||
load_thumb = mode == MODE_THUMB && tns.loadnext < tns.end; | load_thumb = mode == MODE_THUMB && tns.loadnext < tns.end; | ||||
if ((load_thumb || to_set || info.fd != -1) && | |||||
if ((init_thumb || load_thumb || to_set || info.fd != -1) && | |||||
XPending(win.env.dpy) == 0) | XPending(win.env.dpy) == 0) | ||||
{ | { | ||||
if (load_thumb) { | if (load_thumb) { | ||||
set_timeout(redraw, TO_REDRAW_THUMBS, false); | set_timeout(redraw, TO_REDRAW_THUMBS, false); | ||||
if (!tns_load(&tns, tns.loadnext, false)) { | |||||
if (!tns_load(&tns, tns.loadnext, false, false)) { | |||||
remove_file(tns.loadnext, false); | remove_file(tns.loadnext, false); | ||||
tns.dirty = true; | tns.dirty = true; | ||||
} | } | ||||
while (tns.loadnext < tns.end && tns.thumbs[tns.loadnext].im != NULL) | |||||
tns.loadnext++; | |||||
if (tns.loadnext >= tns.end) | if (tns.loadnext >= tns.end) | ||||
redraw(); | redraw(); | ||||
} else if (init_thumb) { | |||||
set_timeout(redraw, TO_REDRAW_THUMBS, false); | |||||
if (!tns_load(&tns, tns.initnext, false, true)) | |||||
remove_file(tns.initnext, false); | |||||
} else { | } else { | ||||
xfd = ConnectionNumber(win.env.dpy); | xfd = ConnectionNumber(win.env.dpy); | ||||
FD_ZERO(&fds); | FD_ZERO(&fds); | ||||
@@ -899,8 +905,8 @@ int main(int argc, char **argv) | |||||
if (options->thumb_mode) { | if (options->thumb_mode) { | ||||
mode = MODE_THUMB; | mode = MODE_THUMB; | ||||
tns_init(&tns, files, &filecnt, &fileidx, &win); | tns_init(&tns, files, &filecnt, &fileidx, &win); | ||||
while (!tns_load(&tns, 0, false)) | |||||
remove_file(0, false); | |||||
while (!tns_load(&tns, fileidx, false, false)) | |||||
remove_file(fileidx, false); | |||||
} else { | } else { | ||||
mode = MODE_IMAGE; | mode = MODE_IMAGE; | ||||
tns.thumbs = NULL; | tns.thumbs = NULL; | ||||
@@ -152,7 +152,7 @@ void tns_clean_cache(tns_t *tns) | |||||
} | } | ||||
void tns_init(tns_t *tns, const fileinfo_t *files, const int *cnt, int *sel, | |||||
void tns_init(tns_t *tns, fileinfo_t *files, const int *cnt, int *sel, | |||||
win_t *win) | win_t *win) | ||||
{ | { | ||||
int len; | int len; | ||||
@@ -169,7 +169,8 @@ void tns_init(tns_t *tns, const fileinfo_t *files, const int *cnt, int *sel, | |||||
} | } | ||||
tns->files = files; | tns->files = files; | ||||
tns->cnt = cnt; | tns->cnt = cnt; | ||||
tns->loadnext = tns->first = tns->end = tns->r_first = tns->r_end = 0; | |||||
tns->initnext = tns->loadnext = 0; | |||||
tns->first = tns->end = tns->r_first = tns->r_end = 0; | |||||
tns->sel = sel; | tns->sel = sel; | ||||
tns->win = win; | tns->win = win; | ||||
tns->dirty = false; | tns->dirty = false; | ||||
@@ -237,7 +238,7 @@ Imlib_Image tns_scale_down(Imlib_Image im, int dim) | |||||
return im; | return im; | ||||
} | } | ||||
bool tns_load(tns_t *tns, int n, bool force) | |||||
bool tns_load(tns_t *tns, int n, bool force, bool cache_only) | |||||
{ | { | ||||
int w, h; | int w, h; | ||||
int maxwh = thumb_sizes[ARRLEN(thumb_sizes)-1]; | int maxwh = thumb_sizes[ARRLEN(thumb_sizes)-1]; | ||||
@@ -245,8 +246,8 @@ bool tns_load(tns_t *tns, int n, bool force) | |||||
char *cfile; | char *cfile; | ||||
float zw, zh; | float zw, zh; | ||||
thumb_t *t; | thumb_t *t; | ||||
fileinfo_t *file; | |||||
Imlib_Image im = NULL; | Imlib_Image im = NULL; | ||||
const fileinfo_t *file; | |||||
if (tns == NULL || tns->thumbs == NULL) | if (tns == NULL || tns->thumbs == NULL) | ||||
return false; | return false; | ||||
@@ -261,6 +262,7 @@ bool tns_load(tns_t *tns, int n, bool force) | |||||
if (t->im != NULL) { | if (t->im != NULL) { | ||||
imlib_context_set_image(t->im); | imlib_context_set_image(t->im); | ||||
imlib_free_image(); | imlib_free_image(); | ||||
t->im = NULL; | |||||
} | } | ||||
if (!force) { | if (!force) { | ||||
@@ -345,10 +347,10 @@ bool tns_load(tns_t *tns, int n, bool force) | |||||
warn("could not open image: %s", file->name); | warn("could not open image: %s", file->name); | ||||
return false; | return false; | ||||
} | } | ||||
imlib_context_set_image(im); | |||||
if (!cache_hit) { | if (!cache_hit) { | ||||
#if HAVE_LIBEXIF | #if HAVE_LIBEXIF | ||||
imlib_context_set_image(im); | |||||
exif_auto_orientate(file); | exif_auto_orientate(file); | ||||
#endif | #endif | ||||
im = tns_scale_down(im, maxwh); | im = tns_scale_down(im, maxwh); | ||||
@@ -357,12 +359,22 @@ bool tns_load(tns_t *tns, int n, bool force) | |||||
tns_cache_write(im, file->path, true); | tns_cache_write(im, file->path, true); | ||||
} | } | ||||
t->im = tns_scale_down(im, thumb_sizes[tns->zl]); | |||||
imlib_context_set_image(t->im); | |||||
t->w = imlib_image_get_width(); | |||||
t->h = imlib_image_get_height(); | |||||
if (cache_only) { | |||||
imlib_free_image_and_decache(); | |||||
} else { | |||||
t->im = tns_scale_down(im, thumb_sizes[tns->zl]); | |||||
imlib_context_set_image(t->im); | |||||
t->w = imlib_image_get_width(); | |||||
t->h = imlib_image_get_height(); | |||||
tns->dirty = true; | |||||
} | |||||
file->flags |= FF_TN_INIT; | |||||
if (n == tns->initnext) | |||||
while (++tns->initnext < *tns->cnt && ((++file)->flags & FF_TN_INIT)); | |||||
if (n == tns->loadnext && !cache_only) | |||||
while (++tns->loadnext < tns->end && (++t)->im != NULL); | |||||
tns->dirty = true; | |||||
return true; | return true; | ||||
} | } | ||||
@@ -34,10 +34,11 @@ typedef struct { | |||||
} thumb_t; | } thumb_t; | ||||
typedef struct { | typedef struct { | ||||
const fileinfo_t *files; | |||||
fileinfo_t *files; | |||||
thumb_t *thumbs; | thumb_t *thumbs; | ||||
const int *cnt; | const int *cnt; | ||||
int *sel; | int *sel; | ||||
int initnext; | |||||
int loadnext; | int loadnext; | ||||
int first, end; | int first, end; | ||||
int r_first, r_end; | int r_first, r_end; | ||||
@@ -56,10 +57,10 @@ typedef struct { | |||||
void tns_clean_cache(tns_t*); | void tns_clean_cache(tns_t*); | ||||
void tns_init(tns_t*, const fileinfo_t*, const int*, int*, win_t*); | |||||
void tns_init(tns_t*, fileinfo_t*, const int*, int*, win_t*); | |||||
void tns_free(tns_t*); | void tns_free(tns_t*); | ||||
bool tns_load(tns_t*, int, bool); | |||||
bool tns_load(tns_t*, int, bool, bool); | |||||
void tns_unload(tns_t*, int); | void tns_unload(tns_t*, int); | ||||
void tns_render(tns_t*); | void tns_render(tns_t*); | ||||
@@ -65,8 +65,9 @@ typedef enum { | |||||
} cursor_t; | } cursor_t; | ||||
typedef enum { | typedef enum { | ||||
FF_WARN = 1, | |||||
FF_MARK = 2 | |||||
FF_WARN = 1, | |||||
FF_MARK = 2, | |||||
FF_TN_INIT = 4 | |||||
} fileflags_t; | } fileflags_t; | ||||
typedef struct { | typedef struct { | ||||