winwidget winwidget_create_from_file(gib_list * list, char type) { winwidget ret = NULL; feh_file *file = FEH_FILE(list->data); if (!file || !file->filename) return(NULL); ret = winwidget_allocate(); ret->file = list; ret->type = type; if ((winwidget_loadimage(ret, file) == 0) || feh_should_ignore_image(ret->im)) { winwidget_destroy(ret); return(NULL); } if (!ret->win) { ret->w = ret->im_w = gib_imlib_image_get_width(ret->im); ret->h = ret->im_h = gib_imlib_image_get_height(ret->im); D(("image is %dx%d pixels, format %s\n", ret->w, ret->h, gib_imlib_image_format(ret->im))); if (opt.full_screen) ret->full_screen = True; winwidget_create_window(ret, ret->w, ret->h); winwidget_render_image(ret, 1, 0); } return(ret); }
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; }