Exemple #1
0
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;

	if (!winwid->full_screen && resize) {
		winwidget_resize(winwid, winwid->im_w, winwid->im_h, 0);
		winwidget_reset_image(winwid);
	}

	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) resets the winwid->had_resize flag */
	int had_resize = winwid->had_resize || resize;

	winwidget_setup_pixmaps(winwid);

	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 ((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 (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;
			}
		} else {
			winwid->im_x = (int) (winwid->w - (winwid->im_w * 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 {
				winwid->im_y = - opt.offset_y * winwid->zoom;
			}
		} else {
			winwid->im_y = (int) (winwid->h - (winwid->im_h * winwid->zoom)) >> 1;
		}
	}
Exemple #2
0
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);
		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 && opt.scale_down && ((winwid->w < winwid->im_w)
						       || (winwid->h < winwid->im_h)) &&
							  (winwid->type != WIN_TYPE_THUMBNAIL) &&
							  (winwid->old_zoom == 1.0)) {
		D(("scaling down image %dx%d\n", winwid->w, winwid->h));

		feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, winwid->w, winwid->h);
		if (resize)
			 winwidget_resize(winwid, winwid->im_w * winwid->zoom, winwid->im_h * winwid->zoom);
		D(("after scaling down image %dx%d\n", winwid->w, winwid->h));
	}

	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);

	if (!winwid->full_screen && opt.zoom_mode
				     && (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);


	if (resize && (winwid->full_screen || (opt.geom_flags & (WidthValue | HeightValue)))) {
		int smaller;	/* Is the image smaller than screen? */
		int max_w = 0, max_h = 0;

		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;
			}
#endif				/* HAVE_LIBXINERAMA */
		} else {
			if (opt.geom_flags & WidthValue) {
				max_w = opt.geom_w;
			}
			if (opt.geom_flags & HeightValue) {
				max_h = opt.geom_h;
			}
		}

		D(("Calculating for fullscreen/fixed geom render\n"));
		smaller = ((winwid->im_w < max_w)
			   && (winwid->im_h < max_h));

		if (!smaller || opt.zoom_mode) {
			double ratio = 0.0;

			/* Image is larger than the screen (so wants shrinking), or it's
			   smaller but wants expanding to fill it */
			ratio = feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, max_w, max_h);

			/* contributed by Jens Laas <*****@*****.**>
			 * 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 (winwid->zoom != 1.0) {
					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;
			} else {
Exemple #3
0
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;
}
Exemple #4
0
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;
}
Exemple #5
0
void feh_menu_cb(feh_menu * m, feh_menu_item * i, int action, void *data)
{
	char *path;
	Imlib_Image im;
	winwidget winwid;

	switch (action) {
		case CB_BG_TILED:
			path = feh_absolute_path(FEH_FILE(m->fehwin->file->data)->filename);
			feh_wm_set_bg(path, m->fehwin->im, 0, 0, 0, (int) data, 1);
			free(path);
			break;
		case CB_BG_SCALED:
			path = feh_absolute_path(FEH_FILE(m->fehwin->file->data)->filename);
			feh_wm_set_bg(path, m->fehwin->im, 0, 1, 0, (int) data, 1);
			free(path);
			break;
		case CB_BG_CENTERED:
			path = feh_absolute_path(FEH_FILE(m->fehwin->file->data)->filename);
			feh_wm_set_bg(path, m->fehwin->im, 1, 0, 0, (int) data, 1);
			free(path);
			break;
		case CB_BG_FILLED:
			path = feh_absolute_path(FEH_FILE(m->fehwin->file->data)->filename);
			feh_wm_set_bg(path, m->fehwin->im, 0, 0, 1, (int) data, 1);
			free(path);
			break;
		case CB_BG_TILED_NOFILE:
			feh_wm_set_bg(NULL, m->fehwin->im, 0, 0, 0, (int) data, 1);
			break;
		case CB_BG_SCALED_NOFILE:
			feh_wm_set_bg(NULL, m->fehwin->im, 0, 1, 0, (int) data, 1);
			break;
		case CB_BG_CENTERED_NOFILE:
			feh_wm_set_bg(NULL, m->fehwin->im, 1, 0, 0, (int) data, 1);
			break;
		case CB_BG_FILLED_NOFILE:
			feh_wm_set_bg(NULL, m->fehwin->im, 0, 0, 1, (int) data, 1);
			break;
		case CB_ABOUT:
			if (feh_load_image_char(&im, PREFIX "/share/feh/images/about.png")
					!= 0) {
				winwid = winwidget_create_from_image(im, "About " PACKAGE,
						WIN_TYPE_ABOUT);
				winwid->file = gib_list_add_front(NULL,
						feh_file_new(PREFIX "/share/feh/images/about.png"));
				winwidget_show(winwid);
			}
			break;
		case CB_CLOSE:
			winwidget_destroy(m->fehwin);
			break;
		case CB_EXIT:
			winwidget_destroy_all();
			break;
		case CB_RESET:
			if (m->fehwin->has_rotated) {
				m->fehwin->im_w = gib_imlib_image_get_width(m->fehwin->im);
				m->fehwin->im_h = gib_imlib_image_get_height(m->fehwin->im);
				winwidget_resize(m->fehwin, m->fehwin->im_w, m->fehwin->im_h);
			}
			winwidget_reset_image(m->fehwin);
			winwidget_render_image(m->fehwin, 1, 1);
			break;
		case CB_RELOAD:
			feh_reload_image(m->fehwin, 0, 0);
			break;
		case CB_REMOVE:
			feh_filelist_image_remove(m->fehwin, 0);
			break;
		case CB_DELETE:
			feh_filelist_image_remove(m->fehwin, 1);
			break;
		case CB_REMOVE_THUMB:
			feh_thumbnail_mark_removed(FEH_FILE(m->fehwin->file->data), 0);
			feh_filelist_image_remove(m->fehwin, 0);
			break;
		case CB_DELETE_THUMB:
			feh_thumbnail_mark_removed(FEH_FILE(m->fehwin->file->data), 1);
			feh_filelist_image_remove(m->fehwin, 1);
			break;
		case CB_SORT_FILENAME:
			filelist = gib_list_sort(filelist, feh_cmp_filename);
			if (opt.jump_on_resort) {
				slideshow_change_image(m->fehwin, SLIDE_FIRST);
			}
			break;
		case CB_SORT_IMAGENAME:
			filelist = gib_list_sort(filelist, feh_cmp_name);
			if (opt.jump_on_resort) {
				slideshow_change_image(m->fehwin, SLIDE_FIRST);
			}
			break;
		case CB_SORT_FILESIZE:
			filelist = gib_list_sort(filelist, feh_cmp_size);
			if (opt.jump_on_resort) {
				slideshow_change_image(m->fehwin, SLIDE_FIRST);
			}
			break;
		case CB_SORT_RANDOMIZE:
			filelist = gib_list_randomize(filelist);
			if (opt.jump_on_resort) {
				slideshow_change_image(m->fehwin, SLIDE_FIRST);
			}
			break;
		case CB_FIT:
			winwidget_size_to_image(m->fehwin);
			break;
		case CB_EDIT_ROTATE:
			feh_edit_inplace_orient(m->fehwin, (int) data);
			break;
		case CB_SAVE_IMAGE:
			slideshow_save_image(m->fehwin);
			break;
		case CB_SAVE_FILELIST:
			feh_save_filelist();
			break;
		case CB_OPT_DRAW_FILENAME:
			MENU_ITEM_TOGGLE(i);
			if (MENU_ITEM_IS_ON(i))
				opt.draw_filename = TRUE;
			else
				opt.draw_filename = FALSE;
			winwidget_rerender_all(0, 1);
			break;
		case CB_OPT_DRAW_ACTIONS:
			MENU_ITEM_TOGGLE(i);
			if (MENU_ITEM_IS_ON(i))
				opt.draw_actions = TRUE;
			else
				opt.draw_actions = FALSE;
			winwidget_rerender_all(0, 1);
			break;
		case CB_OPT_KEEP_HTTP:
			MENU_ITEM_TOGGLE(i);
			if (MENU_ITEM_IS_ON(i))
				opt.keep_http = TRUE;
			else
				opt.keep_http = FALSE;
			break;
		case CB_OPT_FREEZE_WINDOW:
			MENU_ITEM_TOGGLE(i);
			if (MENU_ITEM_IS_ON(i)) {
				opt.geom_flags = (WidthValue | HeightValue);
				opt.geom_w = m->fehwin->w;
				opt.geom_h = m->fehwin->h;
			} else {
				opt.geom_flags = 0;
			}
			break;
		case CB_OPT_FULLSCREEN:
			feh_menu_cb_opt_fullscreen(m, i);
			break;
		case CB_OPT_AUTO_ZOOM:
			MENU_ITEM_TOGGLE(i);
			if (MENU_ITEM_IS_ON(i))
				opt.zoom_mode = ZOOM_MODE_FILL;
			else
				opt.zoom_mode = 0;
			winwidget_rerender_all(1, 1);
			break;
	}
	return;
}
Exemple #6
0
void feh_menu_cb(feh_menu * m, feh_menu_item * i, int action, unsigned short data)
{
	char *path;

	switch (action) {
		case CB_BG_TILED:
			path = FEH_FILE(m->fehwin->file->data)->filename;
			feh_wm_set_bg(path, m->fehwin->im, 0, 0, 0, data, 0);
			break;
		case CB_BG_SCALED:
			path = FEH_FILE(m->fehwin->file->data)->filename;
			feh_wm_set_bg(path, m->fehwin->im, 0, 1, 0, data, 0);
			break;
		case CB_BG_CENTERED:
			path = FEH_FILE(m->fehwin->file->data)->filename;
			feh_wm_set_bg(path, m->fehwin->im, 1, 0, 0, data, 0);
			break;
		case CB_BG_FILLED:
			path = FEH_FILE(m->fehwin->file->data)->filename;
			feh_wm_set_bg(path, m->fehwin->im, 0, 0, 1, data, 0);
			break;
		case CB_BG_TILED_NOFILE:
			feh_wm_set_bg(NULL, m->fehwin->im, 0, 0, 0, data, 0);
			break;
		case CB_BG_SCALED_NOFILE:
			feh_wm_set_bg(NULL, m->fehwin->im, 0, 1, 0, data, 0);
			break;
		case CB_BG_CENTERED_NOFILE:
			feh_wm_set_bg(NULL, m->fehwin->im, 1, 0, 0, data, 0);
			break;
		case CB_BG_FILLED_NOFILE:
			feh_wm_set_bg(NULL, m->fehwin->im, 0, 0, 1, data, 0);
			break;
		case CB_CLOSE:
			winwidget_destroy(m->fehwin);
			break;
		case CB_EXIT:
			winwidget_destroy_all();
			break;
		case CB_RESET:
			if (m->fehwin->has_rotated) {
				m->fehwin->im_w = gib_imlib_image_get_width(m->fehwin->im);
				m->fehwin->im_h = gib_imlib_image_get_height(m->fehwin->im);
				winwidget_resize(m->fehwin, m->fehwin->im_w, m->fehwin->im_h);
			}
			winwidget_reset_image(m->fehwin);
			winwidget_render_image(m->fehwin, 1, 0);
			break;
		case CB_RELOAD:
			feh_reload_image(m->fehwin, 0, 1);
			break;
		case CB_REMOVE:
			feh_filelist_image_remove(m->fehwin, 0);
			break;
		case CB_DELETE:
			feh_filelist_image_remove(m->fehwin, 1);
			break;
		case CB_REMOVE_THUMB:
			feh_thumbnail_mark_removed(FEH_FILE(m->fehwin->file->data), 0);
			feh_filelist_image_remove(m->fehwin, 0);
			break;
		case CB_DELETE_THUMB:
			feh_thumbnail_mark_removed(FEH_FILE(m->fehwin->file->data), 1);
			feh_filelist_image_remove(m->fehwin, 1);
			break;
		case CB_SORT_FILENAME:
			filelist = gib_list_sort(filelist, feh_cmp_filename);
			if (opt.jump_on_resort) {
				slideshow_change_image(m->fehwin, SLIDE_FIRST, 1);
			}
			break;
		case CB_SORT_IMAGENAME:
			filelist = gib_list_sort(filelist, feh_cmp_name);
			if (opt.jump_on_resort) {
				slideshow_change_image(m->fehwin, SLIDE_FIRST, 1);
			}
			break;
		case CB_SORT_FILESIZE:
			filelist = gib_list_sort(filelist, feh_cmp_size);
			if (opt.jump_on_resort) {
				slideshow_change_image(m->fehwin, SLIDE_FIRST, 1);
			}
			break;
		case CB_SORT_RANDOMIZE:
			filelist = gib_list_randomize(filelist);
			if (opt.jump_on_resort) {
				slideshow_change_image(m->fehwin, SLIDE_FIRST, 1);
			}
			break;
		case CB_FIT:
			winwidget_size_to_image(m->fehwin);
			break;
		case CB_EDIT_ROTATE:
			feh_edit_inplace(m->fehwin, data);
			break;
		case CB_SAVE_IMAGE:
			slideshow_save_image(m->fehwin);
			break;
		case CB_SAVE_FILELIST:
			feh_save_filelist();
			break;
		case CB_OPT_DRAW_FILENAME:
			MENU_ITEM_TOGGLE(i);
			if (MENU_ITEM_IS_ON(i))
				opt.draw_filename = TRUE;
			else
				opt.draw_filename = FALSE;
			winwidget_rerender_all(0);
			break;
		case CB_OPT_DRAW_ACTIONS:
			MENU_ITEM_TOGGLE(i);
			if (MENU_ITEM_IS_ON(i))
				opt.draw_actions = TRUE;
			else
				opt.draw_actions = FALSE;
			winwidget_rerender_all(0);
			break;
		case CB_OPT_KEEP_HTTP:
			MENU_ITEM_TOGGLE(i);
			if (MENU_ITEM_IS_ON(i))
				opt.keep_http = TRUE;
			else
				opt.keep_http = FALSE;
			break;
		case CB_OPT_FREEZE_WINDOW:
			MENU_ITEM_TOGGLE(i);
			if (MENU_ITEM_IS_ON(i)) {
				opt.geom_flags = (WidthValue | HeightValue);
				opt.geom_w = m->fehwin->w;
				opt.geom_h = m->fehwin->h;
			} else {
				opt.geom_flags = 0;
			}
			break;
		case CB_OPT_FULLSCREEN:
			feh_menu_cb_opt_fullscreen(m, i);
			break;
		case CB_OPT_AUTO_ZOOM:
			MENU_ITEM_TOGGLE(i);
			if (MENU_ITEM_IS_ON(i))
				opt.zoom_mode = ZOOM_MODE_MAX;
			else
				opt.zoom_mode = 0;
			winwidget_rerender_all(1);
			break;
		case CB_OPT_KEEP_ZOOM_VP:
			MENU_ITEM_TOGGLE(i);
			if (MENU_ITEM_IS_ON(i))
				opt.keep_zoom_vp = 1;
			else
				opt.keep_zoom_vp = 0;
			break;
	}
	return;
}
Exemple #7
0
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;
}