void feh_reload_image(winwidget w, int resize, int force_new) { char *title, *new_title; int len; 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); return; } D(("resize %d, force_new %d\n", resize, force_new)); free(FEH_FILE(w->file->data)->caption); FEH_FILE(w->file->data)->caption = NULL; 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); old_w = gib_imlib_image_get_width(w->im); old_h = gib_imlib_image_get_height(w->im); /* * If we don't free the old image before loading the new one, Imlib2's * caching will get in our way. * However, if --reload is used (force_new == 0), we want to continue if * the new image cannot be loaded, so we must not free the old image yet. */ if (force_new) winwidget_free_image(w); if ((feh_load_image(&tmp, FEH_FILE(w->file->data))) == 0) { if (force_new) eprintf("failed to reload image\n"); else { 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; } if (!resize && ((old_w != gib_imlib_image_get_width(tmp)) || (old_h != gib_imlib_image_get_height(tmp)))) resize = 1; if (!force_new) winwidget_free_image(w); w->im = tmp; winwidget_reset_image(w); w->mode = MODE_NORMAL; if ((w->im_w != gib_imlib_image_get_width(w->im)) || (w->im_h != gib_imlib_image_get_height(w->im))) w->had_resize = 1; if (w->has_rotated) { Imlib_Image temp; temp = gib_imlib_create_rotated_image(w->im, 0.0); w->im_w = gib_imlib_image_get_width(temp); w->im_h = gib_imlib_image_get_height(temp); gib_imlib_free_image_and_decache(temp); } else { 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_rename(w, title); free(title); free(new_title); return; }
void slideshow_change_image(winwidget winwid, int change, int render) { gib_list *last = NULL; int i = 0; int jmp = 1; /* We can't use filelist_len in the for loop, since that changes when we * encounter invalid images. */ int our_filelist_len = filelist_len; char *s; unsigned char tmode =0; int tim_x =0; int tim_y =0; double tzoom =0; /* Without this, clicking a one-image slideshow reloads it. Not very * intelligent behaviour :-) */ if (filelist_len < 2 && opt.cycle_once == 0) return; /* Ok. I do this in such an odd way to ensure that if the last or first * image is not loadable, it will go through in the right direction to * find the correct one. Otherwise SLIDE_LAST would try the last file, * then loop forward to find a loadable one. */ if (change == SLIDE_FIRST) { current_file = gib_list_last(filelist); change = SLIDE_NEXT; } else if (change == SLIDE_LAST) { current_file = filelist; change = SLIDE_PREV; } /* The for loop prevents us looping infinitely */ for (i = 0; i < our_filelist_len; i++) { winwidget_free_image(winwid); switch (change) { case SLIDE_NEXT: current_file = feh_list_jump(filelist, current_file, FORWARD, 1); break; case SLIDE_PREV: current_file = feh_list_jump(filelist, current_file, BACK, 1); break; case SLIDE_RAND: if (filelist_len > 1) { current_file = feh_list_jump(filelist, current_file, FORWARD, (rand() % (filelist_len - 1)) + 1); change = SLIDE_NEXT; } break; case SLIDE_JUMP_FWD: if (filelist_len < 5) jmp = 1; else if (filelist_len < 40) jmp = 2; else jmp = filelist_len / 20; if (!jmp) jmp = 2; current_file = feh_list_jump(filelist, current_file, FORWARD, jmp); /* important. if the load fails, we only want to step on ONCE to try the next file, not another jmp */ change = SLIDE_NEXT; break; case SLIDE_JUMP_BACK: if (filelist_len < 5) jmp = 1; else if (filelist_len < 40) jmp = 2; else jmp = filelist_len / 20; if (!jmp) jmp = 2; current_file = feh_list_jump(filelist, current_file, BACK, jmp); /* important. if the load fails, we only want to step back ONCE to try the previous file, not another jmp */ change = SLIDE_NEXT; break; default: eprintf("BUG!\n"); break; } if (last) { filelist = feh_file_remove_from_list(filelist, last); last = NULL; } if (opt.keep_zoom_vp) { /* pre loadimage - record settings */ tmode = winwid->mode; tim_x = winwid->im_x; tim_y = winwid->im_y; tzoom = winwid->zoom; } if ((winwidget_loadimage(winwid, FEH_FILE(current_file->data))) != 0) { winwid->mode = MODE_NORMAL; 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))) 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); if (opt.keep_zoom_vp) { /* put back in: */ winwid->mode = tmode; winwid->im_x = tim_x; winwid->im_y = tim_y; winwid->zoom = tzoom; } if (render) { if (opt.keep_zoom_vp) { winwidget_render_image(winwid, 0, 0); } else { winwidget_render_image(winwid, 1, 0); } } s = slideshow_create_name(FEH_FILE(current_file->data), winwid); winwidget_rename(winwid, s); free(s); break; } else last = current_file; } if (last) filelist = feh_file_remove_from_list(filelist, last); 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; }
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 * encounter invalid images. */ 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.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 * image is not loadable, it will go through in the right direction to * find the correct one. Otherwise SLIDE_LAST would try the last file, * then loop forward to find a loadable one. */ 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 */ for (i = 0; i < our_filelist_len; i++) { winwidget_free_image(winwid); switch (change) { case SLIDE_NEXT: current_file = feh_list_jump(filelist, current_file, FORWARD, 1); break; case SLIDE_PREV: current_file = feh_list_jump(filelist, current_file, BACK, 1); break; case SLIDE_RAND: if (filelist_len > 1) { current_file = feh_list_jump(filelist, current_file, FORWARD, (random() % (filelist_len - 1)) + 1); change = SLIDE_NEXT; } break; case SLIDE_JUMP_FWD: if (filelist_len < 5) jmp = 1; else if (filelist_len < 40) jmp = 2; else jmp = filelist_len / 20; if (!jmp) jmp = 2; current_file = feh_list_jump(filelist, current_file, FORWARD, jmp); /* important. if the load fails, we only want to step on ONCE to try the next file, not another jmp */ change = SLIDE_NEXT; break; case SLIDE_JUMP_BACK: if (filelist_len < 5) jmp = 1; else if (filelist_len < 40) jmp = 2; else jmp = filelist_len / 20; if (!jmp) jmp = 2; current_file = feh_list_jump(filelist, current_file, BACK, jmp); /* important. if the load fails, we only want to step back ONCE to try the previous file, not another jmp */ change = SLIDE_NEXT; break; case SLIDE_JUMP_NEXT_DIR: { char old_dir[PATH_MAX], new_dir[PATH_MAX]; int j; feh_file_dirname(old_dir, FEH_FILE(current_file->data), PATH_MAX); for (j = 0; j < our_filelist_len; j++) { current_file = feh_list_jump(filelist, current_file, FORWARD, 1); feh_file_dirname(new_dir, FEH_FILE(current_file->data), PATH_MAX); if (strcmp(old_dir, new_dir) != 0) break; } } change = SLIDE_NEXT; break; case SLIDE_JUMP_PREV_DIR: { char old_dir[PATH_MAX], new_dir[PATH_MAX]; int j; /* Start the search from the previous file in case we are on the first file of a directory */ current_file = feh_list_jump(filelist, current_file, BACK, 1); feh_file_dirname(old_dir, FEH_FILE(current_file->data), PATH_MAX); for (j = 0; j < our_filelist_len; j++) { current_file = feh_list_jump(filelist, current_file, BACK, 1); feh_file_dirname(new_dir, FEH_FILE(current_file->data), PATH_MAX); if (strcmp(old_dir, new_dir) != 0) break; } /* Next file is the first entry of prev_dir */ current_file = feh_list_jump(filelist, current_file, FORWARD, 1); } change = SLIDE_NEXT; break; default: eprintf("BUG!\n"); break; } if (last) { filelist = feh_file_remove_from_list(filelist, last); last = NULL; } 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; } 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); if (feh_should_ignore_image(winwid->im)) { last = current_file; continue; } winwid->mode = MODE_NORMAL; winwid->file = current_file; if ((winwid->im_w != w) || (winwid->im_h != h)) winwid->had_resize = 1; winwidget_reset_image(winwid); winwid->im_w = w; winwid->im_h = h; if (render) { winwidget_render_image(winwid, 1, 0); } break; } else last = current_file; } if (last) filelist = feh_file_remove_from_list(filelist, last); if (filelist_len == 0) eprintf("No more slides in show"); return; }