Ejemplo n.º 1
0
void feh_filelist_image_remove(winwidget winwid, char do_delete)
{
	if (winwid->type == WIN_TYPE_SLIDESHOW) {
		char *s;
		gib_list *doomed;

		doomed = current_file;
		slideshow_change_image(winwid, SLIDE_NEXT, 0);
		if (do_delete)
			filelist = feh_file_rm_and_free(filelist, doomed);
		else
			filelist = feh_file_remove_from_list(filelist, doomed);
		if (!filelist) {
			/* No more images. Game over ;-) */
			winwidget_destroy(winwid);
			return;
		}
		s = slideshow_create_name(FEH_FILE(winwid->file->data), winwid);
		winwidget_rename(winwid, s);
		free(s);
		winwidget_render_image(winwid, 1, 0);
	} else if ((winwid->type == WIN_TYPE_SINGLE)
		   || (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)) {
		if (do_delete)
			filelist = feh_file_rm_and_free(filelist, winwid->file);
		else
			filelist = feh_file_remove_from_list(filelist, winwid->file);
		winwidget_destroy(winwid);
	}
}
Ejemplo n.º 2
0
static void feh_event_handle_ConfigureNotify(XEvent * ev)
{
	while (XCheckTypedWindowEvent(disp, ev->xconfigure.window, ConfigureNotify, ev));
	if (!menu_root) {
		winwidget w = winwidget_get_from_window(ev->xconfigure.window);

		if (w) {
			D(("configure size %dx%d\n", ev->xconfigure.width, ev->xconfigure.height));
			if ((w->w != ev->xconfigure.width)
					|| (w->h != ev->xconfigure.height)) {
				D(("assigning size and rerendering\n"));
				w->w = ev->xconfigure.width;
				w->h = ev->xconfigure.height;
				w->had_resize = 1;
				if (opt.geom_flags & WidthValue || opt.geom_flags & HeightValue) {
					opt.geom_w = w->w;
					opt.geom_h = w->h;
				}
				winwidget_render_image(w, 0, 0);
			}
		}
	}

	return;
}
Ejemplo n.º 3
0
winwidget winwidget_create_from_file(gib_list * list, char *name, 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 (name)
		ret->name = estrdup(name);
	else
		ret->name = estrdup(file->filename);

	if (winwidget_loadimage(ret, file) == 0) {
		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);
}
Ejemplo n.º 4
0
winwidget winwidget_create_from_image(Imlib_Image im, char *name, char type)
{
	winwidget ret = NULL;

	if (im == NULL)
		return(NULL);

	ret = winwidget_allocate();
	ret->type = type;

	ret->im = im;
	ret->w = ret->im_w = gib_imlib_image_get_width(ret->im);
	ret->h = ret->im_h = gib_imlib_image_get_height(ret->im);

	if (name)
		ret->name = estrdup(name);
	else
		ret->name = estrdup(PACKAGE);

	if (opt.full_screen && (type != WIN_TYPE_THUMBNAIL))
		ret->full_screen = True;
	winwidget_create_window(ret, ret->w, ret->h);
	winwidget_render_image(ret, 1, 0);

	return(ret);
}
Ejemplo n.º 5
0
Archivo: imlib.c Proyecto: Caellian/feh
void feh_edit_inplace(winwidget w, int op)
{
	int tmp;
	Imlib_Image old = NULL;
	Imlib_Load_Error err = IMLIB_LOAD_ERROR_NONE;
	if (!w->file || !w->file->data || !FEH_FILE(w->file->data)->filename)
		return;

	if (!strcmp(gib_imlib_image_format(w->im), "jpeg") &&
			!path_is_url(FEH_FILE(w->file->data)->filename)) {
		feh_edit_inplace_lossless(w, op);
		feh_reload_image(w, 1, 1);
		return;
	}

	old = imlib_load_image_with_error_return(FEH_FILE(w->file->data)->filename, &err);

	if ((old != NULL) && (err == IMLIB_LOAD_ERROR_NONE)) {
		imlib_context_set_image(old);
		if (op == INPLACE_EDIT_FLIP)
			imlib_image_flip_vertical();
		else if (op == INPLACE_EDIT_MIRROR)
			imlib_image_flip_horizontal();
		else
			imlib_image_orientate(op);
		gib_imlib_save_image_with_error_return(old,
			FEH_FILE(w->file->data)->filename, &err);
		gib_imlib_free_image(old);
		if (err)
			feh_imlib_print_load_error(FEH_FILE(w->file->data)->filename,
				w, err);
		feh_reload_image(w, 1, 1);
	} else {
		/*
		 * Image was opened using curl/magick or has been deleted after
		 * opening it
		 */
		imlib_context_set_image(w->im);
		if (op == INPLACE_EDIT_FLIP)
			imlib_image_flip_vertical();
		else if (op == INPLACE_EDIT_MIRROR)
			imlib_image_flip_horizontal();
		else {
			imlib_image_orientate(op);
			tmp = w->im_w;
			FEH_FILE(w->file->data)->info->width = w->im_w = w->im_h;
			FEH_FILE(w->file->data)->info->height = w->im_h = tmp;
		}
		im_weprintf(w, "unable to edit in place. Changes have not been saved.");
		winwidget_render_image(w, 1, 0);
	}

	return;
}
Ejemplo n.º 6
0
Archivo: menu.c Proyecto: talisein/feh
void feh_menu_cb_opt_fullscreen(feh_menu * m, feh_menu_item * i)
{
	int curr_screen = 0;

	MENU_ITEM_TOGGLE(i);
	if (MENU_ITEM_IS_ON(i))
		m->fehwin->full_screen = TRUE;
	else
		m->fehwin->full_screen = FALSE;

#ifdef HAVE_LIBXINERAMA
	if (opt.xinerama && xinerama_screens) {
		int i, rect[4];

		winwidget_get_geometry(m->fehwin, rect);
		/* printf("window: (%d, %d)\n", rect[0], rect[1]);
		   printf("found %d screens.\n", num_xinerama_screens); */
		for (i = 0; i < num_xinerama_screens; i++) {
			xinerama_screen = 0;
			/* printf("%d: [%d, %d, %d, %d] (%d, %d)\n",
			   i,
			   xinerama_screens[i].x_org, xinerama_screens[i].y_org,
			   xinerama_screens[i].width, xinerama_screens[i].height,
			   rect[0], rect[1]); */
			if (XY_IN_RECT(rect[0], rect[1],
				       xinerama_screens[i].x_org,
				       xinerama_screens[i].y_org,
				       xinerama_screens[i].width, xinerama_screens[i].height)) {
				curr_screen = xinerama_screen = i;
				break;
			}

		}
		if (getenv("XINERAMA_SCREEN"))
			curr_screen = xinerama_screen =
				atoi(getenv("XINERAMA_SCREEN"));
	}
#endif				/* HAVE_LIBXINERAMA */

	winwidget_destroy_xwin(m->fehwin);
	winwidget_create_window(m->fehwin, m->fehwin->im_w, m->fehwin->im_h);

	winwidget_render_image(m->fehwin, 1, 1);
	winwidget_show(m->fehwin);

#ifdef HAVE_LIBXINERAMA
	/* if we have xinerama and we're using it, then full screen the window
	 * on the head that the window was active on */
	if (m->fehwin->full_screen == TRUE && opt.xinerama && xinerama_screens) {
		xinerama_screen = curr_screen;
		winwidget_move(m->fehwin, xinerama_screens[curr_screen].x_org, xinerama_screens[curr_screen].y_org);
	}
#endif				/* HAVE_LIBXINERAMA */
}
Ejemplo n.º 7
0
void feh_filelist_image_remove(winwidget winwid, char do_delete)
{
	if (winwid->type == WIN_TYPE_SLIDESHOW) {
		char *s;
		gib_list *doomed;

		doomed = current_file;
		/*
		 * work around feh_list_jump exiting if cycle_once is enabled
		 * and no further files are left (we need to delete first)
		 */
		if (opt.cycle_once && ! doomed->next && do_delete) {
			feh_file_rm_and_free(filelist, doomed);
			exit(0);
		}
		if (doomed->next) {
			slideshow_change_image(winwid, SLIDE_NEXT, 0);
		}
		else {
			slideshow_change_image(winwid, SLIDE_PREV, 0);
		}
		if (do_delete)
			filelist = feh_file_rm_and_free(filelist, doomed);
		else
			filelist = feh_file_remove_from_list(filelist, doomed);
		if (!filelist) {
			/* No more images. Game over ;-) */
			winwidget_destroy(winwid);
			return;
		}
		s = slideshow_create_name(FEH_FILE(winwid->file->data), winwid);
		winwidget_rename(winwid, s);
		free(s);
		winwidget_render_image(winwid, 1, 0);
	} else if ((winwid->type == WIN_TYPE_SINGLE)
		   || (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)) {
		if (do_delete)
			filelist = feh_file_rm_and_free(filelist, winwid->file);
		else
			filelist = feh_file_remove_from_list(filelist, winwid->file);
		winwidget_destroy(winwid);
	}
}
Ejemplo n.º 8
0
Archivo: slideshow.c Proyecto: derf/feh
void feh_filelist_image_remove(winwidget winwid, char do_delete)
{
	if (winwid->type == WIN_TYPE_SLIDESHOW) {
		gib_list *doomed;

		doomed = current_file;
		/*
		 * work around feh_list_jump exiting if ON_LAST_SLIDE_QUIT is set
		 * and no further files are left (we need to delete first)
		 */
		if (opt.on_last_slide == ON_LAST_SLIDE_QUIT && ! doomed->next && do_delete) {
			feh_file_rm_and_free(filelist, doomed);
			exit(0);
		}
		if (doomed->next) {
			slideshow_change_image(winwid, SLIDE_NEXT, 0);
		}
		else {
			slideshow_change_image(winwid, SLIDE_PREV, 0);
		}
		if (do_delete)
			filelist = feh_file_rm_and_free(filelist, doomed);
		else
			filelist = feh_file_remove_from_list(filelist, doomed);
		if (!filelist) {
			/* No more images. Game over ;-) */
			winwidget_destroy(winwid);
			return;
		}
		winwidget_render_image(winwid, 1, 0);
	} else if ((winwid->type == WIN_TYPE_SINGLE)
		   || (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)) {
		if (do_delete)
			filelist = feh_file_rm_and_free(filelist, winwid->file);
		else
			filelist = feh_file_remove_from_list(filelist, winwid->file);
		winwid->file = NULL;
		winwidget_destroy(winwid);
	}
}
Ejemplo n.º 9
0
void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysym, unsigned int button) {
	int curr_screen = 0;

	if (winwid->caption_entry && (keysym != NoSymbol)) {
		switch (keysym) {
		case XK_Return:
			if (state & ControlMask) {
				/* insert actual newline */
				ESTRAPPEND(FEH_FILE(winwid->file->data)->caption, "\n");
				winwidget_render_image_cached(winwid);
			} else {
				/* finish caption entry, write to captions file */
				FILE *fp;
				char *caption_filename;
				caption_filename =
					build_caption_filename(FEH_FILE(winwid->file->data), 1);
				winwid->caption_entry = 0;
				winwidget_render_image_cached(winwid);
				XFreePixmap(disp, winwid->bg_pmap_cache);
				winwid->bg_pmap_cache = 0;
				fp = fopen(caption_filename, "w");
				if (!fp) {
					eprintf("couldn't write to captions file %s:", caption_filename);
					return;
				}
				fprintf(fp, "%s", FEH_FILE(winwid->file->data)->caption);
				free(caption_filename);
				fclose(fp);
			}
			break;
		case XK_Escape:
			/* cancel, revert caption */
			winwid->caption_entry = 0;
			free(FEH_FILE(winwid->file->data)->caption);
			FEH_FILE(winwid->file->data)->caption = NULL;
			winwidget_render_image_cached(winwid);
			XFreePixmap(disp, winwid->bg_pmap_cache);
			winwid->bg_pmap_cache = 0;
			break;
		case XK_BackSpace:
			/* backspace */
			ESTRTRUNC(FEH_FILE(winwid->file->data)->caption, 1);
			winwidget_render_image_cached(winwid);
			break;
		default:
			if (isascii(keysym)) {
				/* append to caption */
				ESTRAPPEND_CHAR(FEH_FILE(winwid->file->data)->caption, keysym);
				winwidget_render_image_cached(winwid);
			}
			break;
		}
		return;
	}

	if (feh_is_kp(EVENT_next_img, state, keysym, button)) {
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_NEXT, 1);
		else if (winwid->type == WIN_TYPE_THUMBNAIL)
			feh_thumbnail_select_next(winwid, 1);
	}
	else if (feh_is_kp(EVENT_prev_img, state, keysym, button)) {
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_PREV, 1);
		else if (winwid->type == WIN_TYPE_THUMBNAIL)
			feh_thumbnail_select_prev(winwid, 1);
	}
	else if (feh_is_kp(EVENT_scroll_right, state, keysym, button)) {
		winwid->im_x -= opt.scroll_step;;
		winwidget_sanitise_offsets(winwid);
		winwidget_render_image(winwid, 0, 1);
	}
	else if (feh_is_kp(EVENT_scroll_left, state, keysym, button)) {
		winwid->im_x += opt.scroll_step;
		winwidget_sanitise_offsets(winwid);
		winwidget_render_image(winwid, 0, 1);
	}
	else if (feh_is_kp(EVENT_scroll_down, state, keysym, button)) {
		winwid->im_y -= opt.scroll_step;
		winwidget_sanitise_offsets(winwid);
		winwidget_render_image(winwid, 0, 1);
	}
	else if (feh_is_kp(EVENT_scroll_up, state, keysym, button)) {
		winwid->im_y += opt.scroll_step;
		winwidget_sanitise_offsets(winwid);
		winwidget_render_image(winwid, 0, 1);
	}
	else if (feh_is_kp(EVENT_scroll_right_page, state, keysym, button)) {
		winwid->im_x -= winwid->w;
		winwidget_sanitise_offsets(winwid);
		winwidget_render_image(winwid, 0, 0);
	}
	else if (feh_is_kp(EVENT_scroll_left_page, state, keysym, button)) {
		winwid->im_x += winwid->w;
		winwidget_sanitise_offsets(winwid);
		winwidget_render_image(winwid, 0, 0);
	}
	else if (feh_is_kp(EVENT_scroll_down_page, state, keysym, button)) {
		winwid->im_y -= winwid->h;
		winwidget_sanitise_offsets(winwid);
		winwidget_render_image(winwid, 0, 0);
	}
	else if (feh_is_kp(EVENT_scroll_up_page, state, keysym, button)) {
		winwid->im_y += winwid->h;
		winwidget_sanitise_offsets(winwid);
		winwidget_render_image(winwid, 0, 0);
	}
	else if (feh_is_kp(EVENT_jump_back, state, keysym, button)) {
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_JUMP_BACK, 1);
		else if (winwid->type == WIN_TYPE_THUMBNAIL)
			feh_thumbnail_select_prev(winwid, 10);
	}
	else if (feh_is_kp(EVENT_jump_fwd, state, keysym, button)) {
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_JUMP_FWD, 1);
		else if (winwid->type == WIN_TYPE_THUMBNAIL)
			feh_thumbnail_select_next(winwid, 10);
	}
	else if (feh_is_kp(EVENT_next_dir, state, keysym, button)) {
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_JUMP_NEXT_DIR, 1);
	}
	else if (feh_is_kp(EVENT_prev_dir, state, keysym, button)) {
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_JUMP_PREV_DIR, 1);
	}
	else if (feh_is_kp(EVENT_quit, state, keysym, button)) {
		winwidget_destroy_all();
	}
	else if (feh_is_kp(EVENT_delete, state, keysym, button)) {
		if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)
			feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 1);
		feh_filelist_image_remove(winwid, 1);
	}
	else if (feh_is_kp(EVENT_remove, state, keysym, button)) {
		if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)
			feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 0);
		feh_filelist_image_remove(winwid, 0);
	}
	else if (feh_is_kp(EVENT_jump_first, state, keysym, button)) {
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_FIRST, 1);
	}
	else if (feh_is_kp(EVENT_jump_last, state, keysym, button)) {
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_LAST, 1);
	}
	else if (feh_is_kp(EVENT_action_0, state, keysym, button)) {
		feh_event_invoke_action(winwid, 0);
	}
	else if (feh_is_kp(EVENT_action_1, state, keysym, button)) {
		feh_event_invoke_action(winwid, 1);
	}
	else if (feh_is_kp(EVENT_action_2, state, keysym, button)) {
		feh_event_invoke_action(winwid, 2);
	}
	else if (feh_is_kp(EVENT_action_3, state, keysym, button)) {
		feh_event_invoke_action(winwid, 3);
	}
	else if (feh_is_kp(EVENT_action_4, state, keysym, button)) {
		feh_event_invoke_action(winwid, 4);
	}
	else if (feh_is_kp(EVENT_action_5, state, keysym, button)) {
		feh_event_invoke_action(winwid, 5);
	}
	else if (feh_is_kp(EVENT_action_6, state, keysym, button)) {
		feh_event_invoke_action(winwid, 6);
	}
	else if (feh_is_kp(EVENT_action_7, state, keysym, button)) {
		feh_event_invoke_action(winwid, 7);
	}
	else if (feh_is_kp(EVENT_action_8, state, keysym, button)) {
		feh_event_invoke_action(winwid, 8);
	}
	else if (feh_is_kp(EVENT_action_9, state, keysym, button)) {
		feh_event_invoke_action(winwid, 9);
	}
	else if (feh_is_kp(EVENT_zoom_in, state, keysym, button)) {
		winwid->old_zoom = winwid->zoom;
		winwid->zoom = winwid->zoom * 1.25;

		if (winwid->zoom > ZOOM_MAX)
			winwid->zoom = ZOOM_MAX;

		winwid->im_x = (winwid->w / 2) - (((winwid->w / 2) - winwid->im_x) /
			winwid->old_zoom * winwid->zoom);
		winwid->im_y = (winwid->h / 2) - (((winwid->h / 2) - winwid->im_y) /
			winwid->old_zoom * winwid->zoom);
		winwidget_sanitise_offsets(winwid);
		winwidget_render_image(winwid, 0, 0);
	}
	else if (feh_is_kp(EVENT_zoom_out, state, keysym, button)) {
		winwid->old_zoom = winwid->zoom;
		winwid->zoom = winwid->zoom * 0.80;

		if (winwid->zoom < ZOOM_MIN)
			winwid->zoom = ZOOM_MIN;

		winwid->im_x = (winwid->w / 2) - (((winwid->w / 2) - winwid->im_x) /
			winwid->old_zoom * winwid->zoom);
		winwid->im_y = (winwid->h / 2) - (((winwid->h / 2) - winwid->im_y) /
			winwid->old_zoom * winwid->zoom);
		winwidget_sanitise_offsets(winwid);
		winwidget_render_image(winwid, 0, 0);
	}
	else if (feh_is_kp(EVENT_zoom_default, state, keysym, button)) {
		winwid->zoom = 1.0;
		winwidget_center_image(winwid);
		winwidget_render_image(winwid, 0, 0);
	}
	else if (feh_is_kp(EVENT_zoom_fit, state, keysym, button)) {
		feh_calc_needed_zoom(&winwid->zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h);
		winwidget_center_image(winwid);
		winwidget_render_image(winwid, 0, 0);
	}
	else if (feh_is_kp(EVENT_zoom_fill, state, keysym, button)) {
		int save_zoom = opt.zoom_mode;
		opt.zoom_mode = ZOOM_MODE_FILL;
		feh_calc_needed_zoom(&winwid->zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h);
		winwidget_center_image(winwid);
		winwidget_render_image(winwid, 0, 0);
		opt.zoom_mode = save_zoom;
	}
	else if (feh_is_kp(EVENT_render, state, keysym, button)) {
		if (winwid->type == WIN_TYPE_THUMBNAIL)
			feh_thumbnail_show_selected();
		else
			winwidget_render_image(winwid, 0, 0);
	}
	else if (feh_is_kp(EVENT_toggle_actions, state, keysym, button)) {
		opt.draw_actions = !opt.draw_actions;
		winwidget_rerender_all(0);
	}
	else if (feh_is_kp(EVENT_toggle_aliasing, state, keysym, button)) {
		opt.force_aliasing = !opt.force_aliasing;
		winwid->force_aliasing = !winwid->force_aliasing;
		winwidget_render_image(winwid, 0, 0);
	}
	else if (feh_is_kp(EVENT_toggle_auto_zoom, state, keysym, button)) {
		opt.zoom_mode = (opt.zoom_mode == 0 ? ZOOM_MODE_MAX : 0);
		winwidget_rerender_all(1);
	}
	else if (feh_is_kp(EVENT_toggle_filenames, state, keysym, button)) {
		opt.draw_filename = !opt.draw_filename;
		winwidget_rerender_all(0);
	}
#ifdef HAVE_LIBEXIF
	else if (feh_is_kp(EVENT_toggle_exif, state, keysym, button)) {
		opt.draw_exif = !opt.draw_exif;
		winwidget_rerender_all(0);
	}
#endif
	else if (feh_is_kp(EVENT_toggle_info, state, keysym, button)) {
		opt.draw_info = !opt.draw_info;
		winwidget_rerender_all(0);
	}
	else if (feh_is_kp(EVENT_toggle_pointer, state, keysym, button)) {
		winwidget_set_pointer(winwid, opt.hide_pointer);
		opt.hide_pointer = !opt.hide_pointer;
	}
	else if (feh_is_kp(EVENT_jump_random, state, keysym, button)) {
		if (winwid->type == WIN_TYPE_THUMBNAIL)
			feh_thumbnail_select_next(winwid, random() % (filelist_len - 1));
		else
			slideshow_change_image(winwid, SLIDE_RAND, 1);
	}
	else if (feh_is_kp(EVENT_toggle_caption, state, keysym, button)) {
		if (opt.caption_path) {
			/*
			 * editing captions in slideshow mode does not make any sense
			 * at all; this is just in case someone accidentally does it...
			 */
			if (opt.slideshow_delay)
				opt.paused = 1;
			winwid->caption_entry = 1;
		}
		winwidget_render_image(winwid, 0, 0);
	}
	else if (feh_is_kp(EVENT_reload_image, state, keysym, button)) {
		feh_reload_image(winwid, 0, 0);
	}
	else if (feh_is_kp(EVENT_toggle_pause, state, keysym, button)) {
		slideshow_pause_toggle(winwid);
	}
	else if (feh_is_kp(EVENT_save_image, state, keysym, button)) {
		slideshow_save_image(winwid);
	}
	else if (feh_is_kp(EVENT_save_filelist, state, keysym, button)) {
		if ((winwid->type == WIN_TYPE_THUMBNAIL)
				|| (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER))
			weprintf("Filelist saving is not supported in thumbnail mode");
		else
			feh_save_filelist();
	}
	else if (feh_is_kp(EVENT_size_to_image, state, keysym, button)) {
		winwidget_size_to_image(winwid);
	}
	else if (!opt.no_menus && feh_is_kp(EVENT_toggle_menu, state, keysym, button)) {
		winwidget_show_menu(winwid);
	}
	else if (feh_is_kp(EVENT_close, state, keysym, button)) {
		winwidget_destroy(winwid);
	}
	else if (feh_is_kp(EVENT_orient_1, state, keysym, button)) {
		feh_edit_inplace(winwid, 1);
	}
	else if (feh_is_kp(EVENT_orient_3, state, keysym, button)) {
		feh_edit_inplace(winwid, 3);
	}
	else if (feh_is_kp(EVENT_flip, state, keysym, button)) {
		feh_edit_inplace(winwid, INPLACE_EDIT_FLIP);
	}
	else if (feh_is_kp(EVENT_mirror, state, keysym, button)) {
		feh_edit_inplace(winwid, INPLACE_EDIT_MIRROR);
	}
	else if (feh_is_kp(EVENT_toggle_fullscreen, state, keysym, button)) {
#ifdef HAVE_LIBXINERAMA
		if (opt.xinerama && xinerama_screens) {
			int i, rect[4];

			winwidget_get_geometry(winwid, rect);
			for (i = 0; i < num_xinerama_screens; i++) {
				xinerama_screen = 0;
				if (XY_IN_RECT(rect[0], rect[1],
							xinerama_screens[i].x_org,
							xinerama_screens[i].y_org,
							xinerama_screens[i].width,
							xinerama_screens[i].height)) {
					curr_screen = xinerama_screen = i;
					break;
				}
			}
			if (opt.xinerama_index >= 0)
				curr_screen = xinerama_screen = opt.xinerama_index;
		}
#endif				/* HAVE_LIBXINERAMA */
		winwid->full_screen = !winwid->full_screen;
		winwidget_destroy_xwin(winwid);
		winwidget_create_window(winwid, winwid->im_w, winwid->im_h);
		winwidget_render_image(winwid, 1, 0);
		winwidget_show(winwid);
#ifdef HAVE_LIBXINERAMA
		/* if we have xinerama and we're using it, then full screen the window
		 * on the head that the window was active on */
		if (winwid->full_screen == TRUE && opt.xinerama && xinerama_screens) {
			xinerama_screen = curr_screen;
			winwidget_move(winwid,
					xinerama_screens[curr_screen].x_org, xinerama_screens[curr_screen].y_org);
		}
#endif				/* HAVE_LIBXINERAMA */
	}
	else if (feh_is_kp(EVENT_reload_plus, state, keysym, button)){
		if (opt.reload < SLIDESHOW_RELOAD_MAX)
			opt.reload++;
		else if (opt.verbose)
			weprintf("Cannot set RELOAD higher than %f seconds.", opt.reload);
	}
	else if (feh_is_kp(EVENT_reload_minus, state, keysym, button)) {
		if (opt.reload > 1)
			opt.reload--;
		else if (opt.verbose)
			weprintf("Cannot set RELOAD lower than 1 second.");
	}
	else if (feh_is_kp(EVENT_toggle_keep_vp, state, keysym, button)) {
		opt.keep_zoom_vp = !opt.keep_zoom_vp;
	}
	else if (feh_is_kp(EVENT_toggle_fixed_geometry, state, keysym, button)) {
		if (opt.geom_flags & ((WidthValue | HeightValue))) {
			opt.geom_flags &= ~(WidthValue | HeightValue);
		} else {
			opt.geom_flags |= (WidthValue | HeightValue);
			opt.geom_w = winwid->w;
			opt.geom_h = winwid->h;
		}
		winwidget_render_image(winwid, 1, 0);
	}
	return;
}
Ejemplo n.º 10
0
static void feh_event_handle_ButtonPress(XEvent * ev)
{
	winwidget winwid = NULL;
	int state, button;

	/* get the heck out if it's a mouse-click on the
	   cover, we'll hide the menus on release */
	if (ev->xbutton.window == menu_cover) {
		return;
	}

	winwid = winwidget_get_from_window(ev->xbutton.window);
	if (winwid == NULL || winwid->caption_entry) {
		return;
	}

	state = ev->xbutton.state & (ControlMask | ShiftMask | Mod1Mask | Mod4Mask);
	button = ev->xbutton.button;

	if (!opt.no_menus && feh_is_bb(&buttons.menu, button, state)) {
		D(("Menu Button Press event\n"));
		winwidget_show_menu(winwid);

	} else if (feh_is_bb(&buttons.rotate, button, state)
		   && (winwid->type != WIN_TYPE_THUMBNAIL)) {
		opt.mode = MODE_ROTATE;
		winwid->mode = MODE_ROTATE;
		D(("rotate starting at %d, %d\n", ev->xbutton.x, ev->xbutton.y));

	} else if (feh_is_bb(&buttons.blur, button, state)
		   && (winwid->type != WIN_TYPE_THUMBNAIL)) {
		opt.mode = MODE_BLUR;
		winwid->mode = MODE_BLUR;
		D(("blur starting at %d, %d\n", ev->xbutton.x, ev->xbutton.y));

	} else if (feh_is_bb(&buttons.pan, button, state)) {
		D(("Next button, but could be pan mode\n"));
		opt.mode = MODE_NEXT;
		winwid->mode = MODE_NEXT;
		D(("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y));
		winwid->click_offset_x = ev->xbutton.x - winwid->im_x;
		winwid->click_offset_y = ev->xbutton.y - winwid->im_y;
		winwid->click_start_time = time(NULL);

	} else if (feh_is_bb(&buttons.zoom, button, state)) {
		D(("Zoom Button Press event\n"));
		opt.mode = MODE_ZOOM;
		winwid->mode = MODE_ZOOM;
		D(("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y));
		winwid->click_offset_x = ev->xbutton.x;
		winwid->click_offset_y = ev->xbutton.y;
		winwid->old_zoom = winwid->zoom;

		/* required to adjust the image position in zoom mode */
		winwid->im_click_offset_x = (winwid->click_offset_x
				- winwid->im_x) / winwid->old_zoom;
		winwid->im_click_offset_y = (winwid->click_offset_y
				- winwid->im_y) / winwid->old_zoom;

	} else if (feh_is_bb(&buttons.zoom_in, button, state)) {
		D(("Zoom_In Button Press event\n"));
		D(("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y));
		winwid->click_offset_x = ev->xbutton.x;
		winwid->click_offset_y = ev->xbutton.y;
		winwid->old_zoom = winwid->zoom;

		/* required to adjust the image position in zoom mode */
		winwid->im_click_offset_x = (winwid->click_offset_x
				- winwid->im_x) / winwid->old_zoom;
		winwid->im_click_offset_y = (winwid->click_offset_y
				- winwid->im_y) / winwid->old_zoom;

		/* copied from zoom_in, keyevents.c */
		winwid->zoom = winwid->zoom * 1.25;

		if (winwid->zoom > ZOOM_MAX)
			winwid->zoom = ZOOM_MAX;

		/* copied from below (ZOOM, feh_event_handle_MotionNotify) */
		winwid->im_x = winwid->click_offset_x
				- (winwid->im_click_offset_x * winwid->zoom);
		winwid->im_y = winwid->click_offset_y
				- (winwid->im_click_offset_y * winwid->zoom);

		winwidget_sanitise_offsets(winwid);
		winwidget_render_image(winwid, 0, 0);

	} else if (feh_is_bb(&buttons.zoom_out, button, state)) {
		D(("Zoom_Out Button Press event\n"));
		D(("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y));
		winwid->click_offset_x = ev->xbutton.x;
		winwid->click_offset_y = ev->xbutton.y;
		winwid->old_zoom = winwid->zoom;

		/* required to adjust the image position in zoom mode */
		winwid->im_click_offset_x = (winwid->click_offset_x
				- winwid->im_x) / winwid->old_zoom;
		winwid->im_click_offset_y = (winwid->click_offset_y
				- winwid->im_y) / winwid->old_zoom;

		/* copied from zoom_out, keyevents.c */
		winwid->zoom = winwid->zoom * 0.80;

		if (winwid->zoom < ZOOM_MIN)
			winwid->zoom = ZOOM_MIN;

		/* copied from below (ZOOM, feh_event_handle_MotionNotify) */
		winwid->im_x = winwid->click_offset_x
				- (winwid->im_click_offset_x * winwid->zoom);
		winwid->im_y = winwid->click_offset_y
				- (winwid->im_click_offset_y * winwid->zoom);

		winwidget_sanitise_offsets(winwid);
		winwidget_render_image(winwid, 0, 0);

	} else if (feh_is_bb(&buttons.reload, button, state)) {
		D(("Reload Button Press event\n"));
			feh_reload_image(winwid, 0, 1);

	} else if (feh_is_bb(&buttons.prev, button, state)) {
		D(("Prev Button Press event\n"));
		if (winwid->type == WIN_TYPE_SLIDESHOW)
			slideshow_change_image(winwid, SLIDE_PREV, 1);

	} else if (feh_is_bb(&buttons.next, button, state)) {
		D(("Next Button Press event\n"));
		if (winwid->type == WIN_TYPE_SLIDESHOW)
			slideshow_change_image(winwid, SLIDE_NEXT, 1);

	} else {
		D(("Received other ButtonPress event\n"));
	}
	return;
}
Ejemplo n.º 11
0
/* TODO s/bit/lot */
void init_thumbnail_mode(void)
{
	/* moved to thumbnail_data:
	   Imlib_Image im_main;
	   Imlib_Image bg_im = NULL;
	   Imlib_Font fn = NULL;
	   Imlib_Font title_fn = NULL;

	   int w = 800, h = 600;
	   int bg_w = 0, bg_h = 0;

	   int text_area_w, text_area_h;
	   int max_column_w = 0;
	 */

	Imlib_Image im_temp;
	int ww = 0, hh = 0, www, hhh, xxx, yyy;
	int x = 0, y = 0;
	winwidget winwid = NULL;
	Imlib_Image im_thumb = NULL;
	unsigned char trans_bg = 0;
	int title_area_h = 0;
	int tw = 0, th = 0;
	int fw_name, fw_size, fw_dim, fh;
	int thumbnailcount = 0;
	feh_file *file = NULL;
	gib_list *l, *last = NULL;
	int lines;
	int index_image_width, index_image_height;
	int x_offset_name = 0, x_offset_dim = 0, x_offset_size = 0;
	char *s;
	unsigned int thumb_counter = 0;

	/* initialize thumbnail mode data */
	td.im_main = NULL;
	td.im_bg = NULL;
	td.font_main = NULL;
	td.font_title = NULL;

	td.w = 640;
	td.h = 480;
	td.bg_w = 0;
	td.bg_h = 0;
	td.thumb_tot_h = 0;
	td.text_area_w = 0;
	td.text_area_h = 0;

	td.vertical = 0;
	td.max_column_w = 0;

	mode = "thumbnail";

	if (opt.font)
		td.font_main = gib_imlib_load_font(opt.font);

	if (!td.font_main)
		td.font_main = gib_imlib_load_font(DEFAULT_FONT);

	if (opt.title_font) {
		int fh, fw;

		td.font_title = gib_imlib_load_font(opt.title_font);
		gib_imlib_get_text_size(td.font_title, "W", NULL, &fw, &fh,
				IMLIB_TEXT_TO_RIGHT);
		title_area_h = fh + 4;
	} else
		td.font_title = imlib_load_font(DEFAULT_FONT_TITLE);

	if ((!td.font_main) || (!td.font_title))
		eprintf("Error loading fonts");

	/* Work out how tall the font is */
	gib_imlib_get_text_size(td.font_main, "W", NULL, &tw, &th,
			IMLIB_TEXT_TO_RIGHT);
	/* For now, allow room for the right number of lines with small gaps */
	td.text_area_h = ((th + 2) * (opt.index_show_name + opt.index_show_size +
				opt.index_show_dim)) + 5;

	/* This includes the text area for index data */
	td.thumb_tot_h = opt.thumb_h + td.text_area_h;

	/* Use bg image dimensions for default size */
	if (opt.bg && opt.bg_file) {
		if (!strcmp(opt.bg_file, "trans"))
			trans_bg = 1;
		else {

			D(3, ("Time to apply a background to blend onto\n"));
			if (feh_load_image_char(&td.im_bg, opt.bg_file) != 0) {
				td.bg_w = gib_imlib_image_get_width(td.im_bg);
				td.bg_h = gib_imlib_image_get_height(td.im_bg);
			}
		}
	}

	/* figure out geometry for the main window and entries */
	feh_thumbnail_calculate_geometry();

	index_image_width = td.w;
	index_image_height = td.h + title_area_h;
	td.im_main = imlib_create_image(index_image_width, index_image_height);
	gib_imlib_image_set_has_alpha(td.im_main, 1);

	if (!td.im_main)
		eprintf("Imlib error creating index image, are you low on RAM?");

	if (td.im_bg)
		gib_imlib_blend_image_onto_image(td.im_main, td.im_bg,
						 gib_imlib_image_has_alpha
						 (td.im_bg), 0, 0, td.bg_w, td.bg_h, 0, 0,
						 td.w, td.h, 1, 0, 0);
	else if (trans_bg) {
		gib_imlib_image_fill_rectangle(td.im_main, 0, 0, td.w,
				td.h + title_area_h, 0, 0, 0, 0);
		gib_imlib_image_set_has_alpha(td.im_main, 1);
	} else {
		/* Colour the background */
		gib_imlib_image_fill_rectangle(td.im_main, 0, 0, td.w,
				td.h + title_area_h, 0, 0, 0, 255);
	}

	/* Create title now */

	if (!opt.title)
		s = estrdup(PACKAGE " [thumbnail mode]");
	else
		s = estrdup(feh_printf(opt.title, NULL));

	if (opt.display) {
		winwid = winwidget_create_from_image(td.im_main, s, WIN_TYPE_THUMBNAIL);
		winwidget_show(winwid);
	}

	/* make sure we have an ~/.thumbnails/normal directory for storing
	   permanent thumbnails */
	td.cache_thumbnails = opt.cache_thumbnails;

	if (td.cache_thumbnails) {
		if (opt.thumb_w > opt.thumb_h)
			td.cache_dim = opt.thumb_w;
		else
			td.cache_dim = opt.thumb_h;

		if (td.cache_dim > 256) {
			/* No caching as specified by standard. Sort of. */
			td.cache_thumbnails = 0;
		} else if (td.cache_dim > 128) {
			td.cache_dim = 256;
			td.cache_dir = estrdup("large");
		} else {
			td.cache_dim = 128;
			td.cache_dir = estrdup("normal");
		}
		feh_thumbnail_setup_thumbnail_dir();
	}

	for (l = filelist; l; l = l->next) {
		file = FEH_FILE(l->data);
		if (last) {
			filelist = feh_file_remove_from_list(filelist, last);
			last = NULL;
		}
		D(4, ("About to load image %s\n", file->filename));
		/*      if (feh_load_image(&im_temp, file) != 0) */
		if (feh_thumbnail_get_thumbnail(&im_temp, file) != 0) {
			if (opt.verbose)
				feh_display_status('.');
			D(4, ("Successfully loaded %s\n", file->filename));
			www = opt.thumb_w;
			hhh = opt.thumb_h;
			ww = gib_imlib_image_get_width(im_temp);
			hh = gib_imlib_image_get_height(im_temp);
			thumbnailcount++;
			if (gib_imlib_image_has_alpha(im_temp))
				imlib_context_set_blend(1);
			else
				imlib_context_set_blend(0);

			if (opt.aspect) {
				double ratio = 0.0;

				/* Keep the aspect ratio for the thumbnail */
				ratio = ((double) ww / hh) / ((double) www / hhh);

				if (ratio > 1.0)
					hhh = opt.thumb_h / ratio;
				else if (ratio != 1.0)
					www = opt.thumb_w * ratio;
			}

			if ((!opt.stretch) && ((www > ww) || (hhh > hh))) {
				/* Don't make the image larger unless stretch is specified */
				www = ww;
				hhh = hh;
			}

			im_thumb = gib_imlib_create_cropped_scaled_image(im_temp, 0, 0,
					ww, hh, www, hhh, 1);
			gib_imlib_free_image_and_decache(im_temp);

			if (opt.alpha) {
				DATA8 atab[256];

				D(3, ("Applying alpha options\n"));
				gib_imlib_image_set_has_alpha(im_thumb, 1);
				memset(atab, opt.alpha_level, sizeof(atab));
				gib_imlib_apply_color_modifier_to_rectangle
				    (im_thumb, 0, 0, www, hhh, NULL, NULL, NULL, atab);
			}

			td.text_area_w = opt.thumb_w;
			/* Now draw on the info text */
			if (opt.index_show_name) {
				gib_imlib_get_text_size(td.font_main, file->name, NULL,
						&fw_name, &fh, IMLIB_TEXT_TO_RIGHT);
				if (fw_name > td.text_area_w)
					td.text_area_w = fw_name;
			}
			if (opt.index_show_dim) {
				gib_imlib_get_text_size(td.font_main,
							create_index_dimension_string(ww, hh),
							NULL, &fw_dim, &fh, IMLIB_TEXT_TO_RIGHT);
				if (fw_dim > td.text_area_w)
					td.text_area_w = fw_dim;
			}
			if (opt.index_show_size) {
				gib_imlib_get_text_size(td.font_main,
							create_index_size_string(file->filename),
							NULL, &fw_size, &fh, IMLIB_TEXT_TO_RIGHT);
				if (fw_size > td.text_area_w)
					td.text_area_w = fw_size;
			}
			if (td.text_area_w > opt.thumb_w)
				td.text_area_w += 5;

			/* offsets for centering text */
			x_offset_name = (td.text_area_w - fw_name) / 2;
			x_offset_dim = (td.text_area_w - fw_dim) / 2;
			x_offset_size = (td.text_area_w - fw_size) / 2;

			if (td.vertical) {
				if (td.text_area_w > td.max_column_w)
					td.max_column_w = td.text_area_w;
				if (y > td.h - td.thumb_tot_h) {
					y = 0;
					x += td.max_column_w;
					td.max_column_w = 0;
				}
				if (x > td.w - td.text_area_w)
					break;
			} else {
				if (x > td.w - td.text_area_w) {
					x = 0;
					y += td.thumb_tot_h;
				}
				if (y > td.h - td.thumb_tot_h)
					break;
			}

			/* center image relative to the text below it (if any) */
			xxx = x + ((td.text_area_w - www) / 2);
			yyy = y;

			if (opt.aspect)
				yyy += (opt.thumb_h - hhh) / 2;

			/* Draw now */
			gib_imlib_blend_image_onto_image(td.im_main,
							 im_thumb,
							 gib_imlib_image_has_alpha
							 (im_thumb), 0, 0,
							 www, hhh, xxx,
							 yyy, www, hhh, 1,
							 gib_imlib_image_has_alpha(im_thumb), 0);

			thumbnails = gib_list_add_front(thumbnails,
					feh_thumbnail_new(file, xxx, yyy, www, hhh));

			gib_imlib_free_image_and_decache(im_thumb);

			lines = 0;
			if (opt.index_show_name)
				gib_imlib_text_draw(td.im_main,
						td.font_main, NULL,
						x + x_offset_name,
						y + opt.thumb_h + (lines++ * (th + 2)) + 2,
						file->name, IMLIB_TEXT_TO_RIGHT,
						255, 255, 255, 255);
			if (opt.index_show_dim)
				gib_imlib_text_draw(td.im_main,
						td.font_main, NULL,
						x + x_offset_dim,
						y + opt.thumb_h + (lines++ * (th + 2)) + 2,
						create_index_dimension_string(ww, hh),
						IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
			if (opt.index_show_size)
				gib_imlib_text_draw(td.im_main,
						td.font_main, NULL,
						x + x_offset_size,
						y + opt.thumb_h + (lines++ * (th + 2)) + 2,
						create_index_size_string(file->filename),
						IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);

			if (td.vertical)
				y += td.thumb_tot_h;
			else
				x += td.text_area_w;
		} else {
			if (opt.verbose)
				feh_display_status('x');
			last = l;
		}
		if (opt.display) {
			/* thumb_counter is unsigned, so no need to catch overflows */
			if (++thumb_counter == opt.thumb_redraw) {
				winwidget_render_image(winwid, 0, 0);
				thumb_counter = 0;
			}
			if (!feh_main_iteration(0))
				exit(0);
		}
	}

	if (thumb_counter != 0)
		winwidget_render_image(winwid, 0, 0);

	if (opt.verbose)
		fprintf(stdout, "\n");

	if (opt.title_font) {
		int fw, fh, fx, fy;
		char *s;

		s = create_index_title_string(thumbnailcount, td.w, td.h);
		gib_imlib_get_text_size(td.font_title, s, NULL, &fw, &fh,
				IMLIB_TEXT_TO_RIGHT);
		fx = (index_image_width - fw) >> 1;
		fy = index_image_height - fh - 2;
		gib_imlib_text_draw(td.im_main, td.font_title, NULL, fx,
				fy, s, IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
	}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
0
void init_collage_mode(void)
{
	Imlib_Image im_main;
	Imlib_Image im_temp;
	int ww, hh, www, hhh, xxx, yyy;
	int w = 800, h = 600;
	int bg_w = 0, bg_h = 0;
	winwidget winwid = NULL;
	Imlib_Image bg_im = NULL, im_thumb = NULL;
	feh_file *file = NULL;
	unsigned char trans_bg = 0;
	gib_list *l, *last = NULL;
	char *s;

	D_ENTER(4);

	mode = "collage";

	/* Use bg image dimensions for default size */
	if (opt.bg && opt.bg_file) {
		if (!strcmp(opt.bg_file, "trans"))
			trans_bg = 1;
		else {

			D(4, ("Time to apply a background to blend onto\n"));
			if (feh_load_image_char(&bg_im, opt.bg_file) != 0) {
				bg_w = gib_imlib_image_get_width(bg_im);
				bg_h = gib_imlib_image_get_height(bg_im);
			}
		}
	}

	if (!opt.limit_w || !opt.limit_h) {
		if (bg_im) {
			if (opt.verbose)
				fprintf(stdout,
					PACKAGE
					" - No size restriction specified for collage.\n"
					" You did specify a background however, so the\n"
					" collage size has defaulted to the size of the image\n");
			opt.limit_w = bg_w;
			opt.limit_h = bg_h;
		} else {
			if (opt.verbose)
				fprintf(stdout,
					PACKAGE
					" - No size restriction specified for collage.\n"
					" - For collage mode, you need to specify width and height.\n"
					" Using defaults (width 800, height 600)\n");
			opt.limit_w = 800;
			opt.limit_h = 600;
		}
	}

	w = opt.limit_w;
	h = opt.limit_h;
	D(4, ("Limiting width to %d and height to %d\n", w, h));

	im_main = imlib_create_image(w, h);

	if (!im_main)
		eprintf("Imlib error creating image");

	if (bg_im)
		gib_imlib_blend_image_onto_image(im_main, bg_im,
				gib_imlib_image_has_alpha(bg_im), 0, 0,
				bg_w, bg_h, 0, 0, w, h, 1, 0, 0);
	else if (trans_bg) {
		gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h, 0, 0, 0, 0);
		gib_imlib_image_set_has_alpha(im_main, 1);
	} else {
		/* Colour the background */
		gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h, 0, 0, 0, 255);
	}

	/* Create the title string */

	if (!opt.title)
		s = estrdup(PACKAGE " [collage mode]");
	else
		s = estrdup(feh_printf(opt.title, NULL));

	if (opt.display) {
		winwid = winwidget_create_from_image(im_main, s, WIN_TYPE_SINGLE);
		winwidget_show(winwid);
	}

	for (l = filelist; l; l = l->next) {
		file = FEH_FILE(l->data);
		if (last) {
			filelist = feh_file_remove_from_list(filelist, last);
			filelist_len--;
			last = NULL;
		}
		D(3, ("About to load image %s\n", file->filename));
		if (feh_load_image(&im_temp, file) != 0) {
			D(3, ("Successfully loaded %s\n", file->filename));
			if (opt.verbose)
				feh_display_status('.');
			www = opt.thumb_w;
			hhh = opt.thumb_h;
			ww = gib_imlib_image_get_width(im_temp);
			hh = gib_imlib_image_get_height(im_temp);

			if (opt.aspect) {
				double ratio = 0.0;

				/* Keep the aspect ratio for the thumbnail */
				ratio = ((double) ww / hh) / ((double) www / hhh);

				if (ratio > 1.0)
					hhh = opt.thumb_h / ratio;
				else if (ratio != 1.0)
					www = opt.thumb_w * ratio;
			}

			if ((!opt.stretch) && ((www > ww) || (hhh > hh))) {
				/* Don't make the image larger unless stretch is specified */
				www = ww;
				hhh = hh;
			}

			/* pick random coords for thumbnail */
			xxx = ((w - www) * ((double) rand() / RAND_MAX));
			yyy = ((h - hhh) * ((double) rand() / RAND_MAX));
			D(5, ("image going on at x=%d, y=%d\n", xxx, yyy));

			im_thumb = gib_imlib_create_cropped_scaled_image(im_temp,
					0, 0, ww, hh, www, hhh, 1);
			gib_imlib_free_image_and_decache(im_temp);

			if (opt.alpha) {
				DATA8 atab[256];

				D(4, ("Applying alpha options\n"));
				gib_imlib_image_set_has_alpha(im_thumb, 1);
				memset(atab, opt.alpha_level, sizeof(atab));
				gib_imlib_apply_color_modifier_to_rectangle(im_thumb,
						0, 0, www, hhh, NULL, NULL, NULL, atab);
			}
			gib_imlib_blend_image_onto_image(im_main, im_thumb,
					gib_imlib_image_has_alpha(im_thumb), 0, 0, www, hhh, xxx,
					yyy,www, hhh, 1, gib_imlib_image_has_alpha(im_thumb), 0);
			gib_imlib_free_image_and_decache(im_thumb);
		} else {
			last = l;
			if (opt.verbose)
				feh_display_status('x');
		}
		if (opt.display) {
			winwidget_render_image(winwid, 0, 0);
			if (!feh_main_iteration(0))
				exit(0);
		}
	}
	if (opt.verbose)
		fprintf(stdout, "\n");

	if (opt.output && opt.output_file) {
		char output_buf[1024];
		if (opt.output_dir)
			snprintf(output_buf, 1024, "%s/%s", opt.output_dir, opt.output_file);
		else
			strncpy(output_buf, opt.output_file, 1024);
		gib_imlib_save_image(im_main, output_buf);
		if (opt.verbose) {
			int tw, th;

			tw = gib_imlib_image_get_width(im_main);
			th = gib_imlib_image_get_height(im_main);
			fprintf(stdout, PACKAGE " - File saved as %s\n", output_buf);
			fprintf(stdout,
				"    - Image is %dx%d pixels and contains %d thumbnails\n",
				tw, th, (tw / opt.thumb_w) * (th / opt.thumb_h));
		}
	}

	if (!opt.display)
		gib_imlib_free_image_and_decache(im_main);
	free(s);
	D_RETURN_(4);
}
Ejemplo n.º 15
0
static void feh_event_handle_ButtonRelease(XEvent * ev)
{
	winwidget winwid = NULL;
	int state = ev->xbutton.state & (ControlMask | ShiftMask | Mod1Mask | Mod4Mask);
	int button = ev->xbutton.button;

	if (menu_root) {
		/* if menus are open, close them, and execute action if needed */

		if (ev->xbutton.window == menu_cover) {
			feh_menu_hide(menu_root, True);
		} else if (menu_root) {
			feh_menu *m;

			if ((m = feh_menu_get_from_window(ev->xbutton.window))) {
				feh_menu_item *i = NULL;

				i = feh_menu_find_selected(m);
				feh_menu_item_activate(m, i);
			}
		}
		return;
	}

	winwid = winwidget_get_from_window(ev->xbutton.window);
	if (winwid == NULL || winwid->caption_entry) {
		return;
	}

	if (feh_is_bb(&buttons.pan, button, state)) {
		if (opt.mode == MODE_PAN) {
			D(("Disabling pan mode\n"));
			opt.mode = MODE_NORMAL;
			winwid->mode = MODE_NORMAL;
			winwidget_sanitise_offsets(winwid);
			winwidget_render_image(winwid, 0, 0);
		} else if (opt.mode == MODE_NEXT) {
			opt.mode = MODE_NORMAL;
			winwid->mode = MODE_NORMAL;
			if (winwid->type == WIN_TYPE_SLIDESHOW)
				slideshow_change_image(winwid, SLIDE_NEXT, 1);
			else if (winwid->type == WIN_TYPE_THUMBNAIL) {
				feh_file *thumbfile;
				int x, y;

				x = ev->xbutton.x;
				y = ev->xbutton.y;
				x -= winwid->im_x;
				y -= winwid->im_y;
				x /= winwid->zoom;
				y /= winwid->zoom;
				thumbfile = feh_thumbnail_get_file_from_coords(x, y);
				if (thumbfile) {
					if (opt.actions[0])
						feh_action_run(thumbfile, opt.actions[0]);
					else
						feh_thumbnail_show_fullsize(thumbfile);
				}
			}
		} else {
			opt.mode = MODE_NORMAL;
			winwid->mode = MODE_NORMAL;
		}

	} else if (feh_is_bb(&buttons.rotate, button, state)
			|| feh_is_bb(&buttons.zoom, button, state)) {
		D(("Disabling mode\n"));
		opt.mode = MODE_NORMAL;
		winwid->mode = MODE_NORMAL;

		if ((feh_is_bb(&buttons.zoom, button, state))
				&& (ev->xbutton.x == winwid->click_offset_x)
				&& (ev->xbutton.y == winwid->click_offset_y)) {
			winwid->zoom = 1.0;
			winwidget_center_image(winwid);
		} else
			winwidget_sanitise_offsets(winwid);

		winwidget_render_image(winwid, 0, 0);

	} else if (feh_is_bb(&buttons.blur, button, state)) {
		D(("Disabling Blur mode\n"));
		opt.mode = MODE_NORMAL;
		winwid->mode = MODE_NORMAL;
	}
	return;
}
Ejemplo n.º 16
0
Archivo: menu.c Proyecto: talisein/feh
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;
}
Ejemplo n.º 17
0
void feh_event_handle_keypress(XEvent * ev)
{
	int len;
	char kbuf[20];
	KeySym keysym;
	XKeyEvent *kev;
	winwidget winwid = NULL;
	int curr_screen = 0;
	feh_menu_item *selected_item;
	feh_menu *selected_menu;

	D_ENTER(4);

	winwid = winwidget_get_from_window(ev->xkey.window);

	/* nuke dupe events, unless we're typing text */
	if (winwid && !winwid->caption_entry) {
		while (XCheckTypedWindowEvent(disp, ev->xkey.window, KeyPress, ev));
	}

	kev = (XKeyEvent *) ev;
	len = XLookupString(&ev->xkey, (char *) kbuf, sizeof(kbuf), &keysym, NULL);

	/* menus are showing, so this is a menu control keypress */
	if (ev->xbutton.window == menu_cover) {
		selected_item = feh_menu_find_selected_r(menu_root, &selected_menu);
		switch (keysym) {
		case XK_Escape:
			feh_menu_hide(menu_root, True);
			break;
		case XK_Left:
			feh_menu_select_parent(selected_menu, selected_item);
			break;
		case XK_Down:
			feh_menu_select_next(selected_menu, selected_item);
			break;
		case XK_Up:
			feh_menu_select_prev(selected_menu, selected_item);
			break;
		case XK_Right:
			feh_menu_select_submenu(selected_menu, selected_item);
			break;
		case XK_Return:
			feh_menu_item_activate(selected_menu, selected_item);
			break;
		default:
			break;
		}
		if (len <= 0 || len > (int) sizeof(kbuf))
			D_RETURN_(4);
		kbuf[len] = '\0';

		switch (*kbuf) {
		case 'h':
			feh_menu_select_parent(selected_menu, selected_item);
			break;
		case 'j':
			feh_menu_select_next(selected_menu, selected_item);
			break;
		case 'k':
			feh_menu_select_prev(selected_menu, selected_item);
			break;
		case 'l':
			feh_menu_select_submenu(selected_menu, selected_item);
			break;
		case ' ':
			feh_menu_item_activate(selected_menu, selected_item);
			break;
		default:
			break;
		}

		D_RETURN_(4);
	}

	if (winwid == NULL)
		D_RETURN_(4);

	if (winwid->caption_entry) {
		switch (keysym) {
		case XK_Return:
			if (kev->state & ControlMask) {
				/* insert actual newline */
				ESTRAPPEND(FEH_FILE(winwid->file->data)->caption, "\n");
				winwidget_render_image_cached(winwid);
			} else {
				/* finish caption entry, write to captions file */
				FILE *fp;
				char *caption_filename;
				caption_filename = build_caption_filename(FEH_FILE(winwid->file->data));
				winwid->caption_entry = 0;
				winwidget_render_image_cached(winwid);
				XFreePixmap(disp, winwid->bg_pmap_cache);
				winwid->bg_pmap_cache = 0;
				fp = fopen(caption_filename, "w");
				if (!fp) {
					weprintf("couldn't write to captions file %s:", caption_filename);
					D_RETURN_(4);
				}
				fprintf(fp, "%s", FEH_FILE(winwid->file->data)->caption);
				free(caption_filename);
				fclose(fp);
			}
			break;
		case XK_Escape:
			/* cancel, revert caption */
			winwid->caption_entry = 0;
			free(FEH_FILE(winwid->file->data)->caption);
			FEH_FILE(winwid->file->data)->caption = NULL;
			winwidget_render_image_cached(winwid);
			XFreePixmap(disp, winwid->bg_pmap_cache);
			winwid->bg_pmap_cache = 0;
			break;
		case XK_BackSpace:
			/* backspace */
			ESTRTRUNC(FEH_FILE(winwid->file->data)->caption, 1);
			winwidget_render_image_cached(winwid);
			break;
		default:
			if (isascii(keysym)) {
				/* append to caption */
				ESTRAPPEND_CHAR(FEH_FILE(winwid->file->data)->caption, keysym);
				winwidget_render_image_cached(winwid);
			}
			break;
		}
		D_RETURN_(4);
	}

	switch (keysym) {
	case XK_Left:
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_PREV);
		break;
	case XK_Right:
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_NEXT);
		break;
	case XK_Page_Up:
	case XK_KP_Page_Up:
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_JUMP_BACK);
		break;
	case XK_Escape:
		winwidget_destroy_all();
		break;
	case XK_Page_Down:
	case XK_KP_Page_Down:
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_JUMP_FWD);
		break;
	case XK_Delete:
		/* Holding ctrl gets you a filesystem deletion and removal from the * 
		   filelist. Just DEL gets you filelist removal only. */
		if (kev->state & ControlMask) {
			if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)
				feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 1);
			feh_filelist_image_remove(winwid, 1);
		} else {
			if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)
				feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 0);
			feh_filelist_image_remove(winwid, 0);
		}
		break;
	case XK_Home:
	case XK_KP_Home:
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_FIRST);
		break;
	case XK_End:
	case XK_KP_End:
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_LAST);
		break;
	case XK_Return:
		feh_event_invoke_action(winwid, opt.actions[0]);
		break;
	case XK_0:
		feh_event_invoke_action(winwid, opt.actions[0]);
		break;
	case XK_1:
		feh_event_invoke_action(winwid, opt.actions[1]);
		break;
	case XK_2:
		feh_event_invoke_action(winwid, opt.actions[2]);
		break;
	case XK_3:
		feh_event_invoke_action(winwid, opt.actions[3]);
		break;
	case XK_4:
		feh_event_invoke_action(winwid, opt.actions[4]);
		break;
	case XK_5:
		feh_event_invoke_action(winwid, opt.actions[5]);
		break;
	case XK_6:
		feh_event_invoke_action(winwid, opt.actions[6]);
		break;
	case XK_7:
		feh_event_invoke_action(winwid, opt.actions[7]);
		break;
	case XK_8:
		feh_event_invoke_action(winwid, opt.actions[8]);
		break;
	case XK_9:
		feh_event_invoke_action(winwid, opt.actions[9]);
		break;
	case XK_KP_Left:
		winwid->im_x = winwid->im_x - 10;
		winwidget_render_image(winwid, 0, 0);
		break;
	case XK_KP_Right:
		winwid->im_x = winwid->im_x + 10;
		winwidget_render_image(winwid, 0, 0);
		break;
	case XK_KP_Up:
		winwid->im_y = winwid->im_y - 10;
		winwidget_render_image(winwid, 0, 0);
		break;
	case XK_KP_Down:
		winwid->im_y = winwid->im_y + 10;
		winwidget_render_image(winwid, 0, 0);
		break;
	case XK_KP_Add:
		/* erroneously recognized as '+' in the *kbuf switch. Work around this. */
		len = 0;
		winwid->zoom = winwid->zoom * 1.25;
		winwidget_render_image(winwid, 0, 0);
		break;
	case XK_KP_Subtract:
		len = 0;
		winwid->zoom = winwid->zoom * 0.75;
		winwidget_render_image(winwid, 0, 0);
		break;
	case XK_KP_Multiply:
		len = 0;
		winwid->zoom = 1;
		winwidget_render_image(winwid, 0, 0);
		break;
	case XK_KP_Divide:
		len = 0;
		feh_calc_needed_zoom(&winwid->zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h);
		winwidget_render_image(winwid, 0, 1);
		break;
	case XK_KP_Begin:
		winwidget_render_image(winwid, 0, 1);
		break;
	default:
		break;
	}

	if (len <= 0 || len > (int) sizeof(kbuf))
		D_RETURN_(4);
	kbuf[len] = '\0';

	switch (*kbuf) {
	case 'a':
	case 'A':
		opt.draw_actions = !opt.draw_actions;
		winwidget_rerender_all(0, 1);
		break;
	case 'd':
	case 'D':
		opt.draw_filename = !opt.draw_filename;
		winwidget_rerender_all(0, 1);
		break;
	case 'n':
	case 'N':
	case ' ':
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_NEXT);
		break;
	case 'p':
	case 'P':
	case '\b':
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_PREV);
		break;
	case 'z':
	case 'Z':
		if (opt.slideshow)
			slideshow_change_image(winwid, SLIDE_RAND);
		break;
	case 'q':
	case 'Q':
		winwidget_destroy_all();
		break;
	case 'c':
	case 'C':
		if (opt.caption_path)
			winwid->caption_entry = 1;
		winwidget_render_image(winwid, 0, 1);
		break;
	case 'r':
	case 'R':
		feh_reload_image(winwid, 0, 0);
		break;
	case 'h':
	case 'H':
		slideshow_pause_toggle(winwid);
		break;
	case 's':
	case 'S':
		slideshow_save_image(winwid);
		break;
	case 'f':
	case 'F':
		feh_save_filelist();
		break;
	case 'w':
	case 'W':
		winwidget_size_to_image(winwid);
		break;
	case 'm':
	case 'M':
		winwidget_show_menu(winwid);
		break;
	case 'x':
	case 'X':
		winwidget_destroy(winwid);
		break;
	case '>':
		feh_edit_inplace_orient(winwid, 1);
		break;
	case '<':
		feh_edit_inplace_orient(winwid, 3);
		break;
	case 'v':
	case 'V':
#ifdef HAVE_LIBXINERAMA
		if (opt.xinerama && xinerama_screens) {
			int i, rect[4];

			winwidget_get_geometry(winwid, rect);
			/* printf("window: (%d, %d)\n", rect[0], rect[1]);
			   printf("found %d screens.\n", num_xinerama_screens); */
			for (i = 0; i < num_xinerama_screens; i++) {
				xinerama_screen = 0;
				/* printf("%d: [%d, %d, %d, %d] (%d, %d)\n",
				   i,
				   xinerama_screens[i].x_org, xinerama_screens[i].y_org,
				   xinerama_screens[i].width, xinerama_screens[i].height,
				   rect[0], rect[1]); */
				if (XY_IN_RECT(rect[0], rect[1],
							xinerama_screens[i].x_org,
							xinerama_screens[i].y_org,
							xinerama_screens[i].width,
							xinerama_screens[i].height)) {
					curr_screen = xinerama_screen = i;
					break;
				}
			}
		}
#endif				/* HAVE_LIBXINERAMA */
		winwid->full_screen = !winwid->full_screen;
		winwidget_destroy_xwin(winwid);
		winwidget_create_window(winwid, winwid->im_w, winwid->im_h);
		winwidget_render_image(winwid, 1, 1);
		winwidget_show(winwid);
#ifdef HAVE_LIBXINERAMA
		/* if we have xinerama and we're using it, then full screen the window
		 * on the head that the window was active on */
		if (winwid->full_screen == TRUE && opt.xinerama && xinerama_screens) {
			xinerama_screen = curr_screen;
			winwidget_move(winwid,
					xinerama_screens[curr_screen].x_org, xinerama_screens[curr_screen].y_org);
		}
#endif				/* HAVE_LIBXINERAMA */
	case '=':
	case '+':
		if (opt.reload < SLIDESHOW_RELOAD_MAX)
			opt.reload++;
		else if (opt.verbose)
			weprintf("Cannot set RELOAD higher than %d seconds.", opt.reload);
		break;
	case '-':
	case '_':
		if (opt.reload > 1)
			opt.reload--;
		else if (opt.verbose)
			weprintf("Cannot set RELOAD lower than 1 second.");
		break;
	default:
		break;
	}
	D_RETURN_(4);
}
Ejemplo n.º 18
0
Archivo: menu.c Proyecto: EvinceMoi/feh
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;
}
Ejemplo n.º 19
0
Archivo: slideshow.c Proyecto: derf/feh
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;
}
Ejemplo n.º 20
0
static void feh_event_handle_MotionNotify(XEvent * ev)
{
	winwidget winwid = NULL;
	int dx, dy;
	int scr_width, scr_height;

	scr_width = scr->width;
	scr_height = scr->height;
#ifdef HAVE_LIBXINERAMA
	if (opt.xinerama && xinerama_screens) {
		scr_width = xinerama_screens[xinerama_screen].width;
		scr_height = xinerama_screens[xinerama_screen].height;
	}
#endif				/* HAVE_LIBXINERAMA */

	if (menu_root) {
		feh_menu *m;
		feh_menu_item *selected_item, *mouseover_item;

		D(("motion notify with menus open\n"));
		while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev));

		if (ev->xmotion.window == menu_cover) {
			return;
		} else if ((m = feh_menu_get_from_window(ev->xmotion.window))) {
			selected_item = feh_menu_find_selected(m);
			mouseover_item = feh_menu_find_at_xy(m, ev->xmotion.x, ev->xmotion.y);

			if (selected_item != mouseover_item) {
				D(("selecting a menu item\n"));
				if (selected_item)
					feh_menu_deselect_selected(m);
				if ((mouseover_item)
						&& ((mouseover_item->action)
							|| (mouseover_item->submenu)
							|| (mouseover_item->func_gen_sub)))
					feh_menu_select(m, mouseover_item);
			}
			/* check if we are close to the right and/or the bottom edge of the
			 * screen. If so, and if the menu we are currently over is partially
			 * hidden, slide the menu to the left and/or up until it is
			 * fully visible */

			/* FIXME: get this working nicely with xinerama screen edges --
			 * at the moment it does really funky stuff with
			 * scr_{width,height} instead of scr->{width,height} -- pabs*/
			if (mouseover_item
					&& ((scr->width - (ev->xmotion.x + m->x)) <
						m->w || (scr->height - (ev->xmotion.y + m->y)) < m->w)) {
				dx = scr_width - (m->x + m->w);
				dy = scr_height - (m->y + m->h);
				dx = dx < 0 ? dx : 0;
				dy = dy < 0 ? dy : 0;
				if (dx || dy)
					feh_menu_slide_all_menus_relative(dx, dy);
			}
			/* if a submenu is open we want to see that also */
			if (mouseover_item && m->next && ((scr->width - (ev->xmotion.x + m->next->x))
						< m->next->w
						|| (scr->height -
							(ev->xmotion.y + m->next->y)) < m->next->w)) {
				dx = scr->width - (m->next->x + m->next->w);
				dy = scr->height - (m->next->y + m->next->h);
				dx = dx < 0 ? dx : 0;
				dy = dy < 0 ? dy : 0;
				if (dx || dy)
					feh_menu_slide_all_menus_relative(dx, dy);
			}
		}
	} else if (opt.mode == MODE_ZOOM) {
		while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev));

		winwid = winwidget_get_from_window(ev->xmotion.window);
		if (winwid) {
			if (ev->xmotion.x > winwid->click_offset_x)
				winwid->zoom = winwid->old_zoom + (
						((double) ev->xmotion.x - (double) winwid->click_offset_x)
						/ 128.0);
			else
				winwid->zoom = winwid->old_zoom - (
						((double) winwid->click_offset_x - (double) ev->xmotion.x)
						/ 128.0);

			if (winwid->zoom < ZOOM_MIN)
				winwid->zoom = ZOOM_MIN;
			else if (winwid->zoom > ZOOM_MAX)
				winwid->zoom = ZOOM_MAX;

			/* center around click_offset */
			winwid->im_x = winwid->click_offset_x
					- (winwid->im_click_offset_x * winwid->zoom);
			winwid->im_y = winwid->click_offset_y
					- (winwid->im_click_offset_y * winwid->zoom);

			winwidget_render_image(winwid, 0, 1);
		}
	} else if ((opt.mode == MODE_PAN) || (opt.mode == MODE_NEXT)) {
		int orig_x, orig_y;

		while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev));
		winwid = winwidget_get_from_window(ev->xmotion.window);
		if (winwid) {
			if (opt.mode == MODE_NEXT) {
				if ((abs(winwid->click_offset_x - (ev->xmotion.x - winwid->im_x)) > FEH_JITTER_OFFSET)
						|| (abs(winwid->click_offset_y - (ev->xmotion.y - winwid->im_y)) > FEH_JITTER_OFFSET)
						|| (time(NULL) - winwid->click_start_time > FEH_JITTER_TIME)) {
					opt.mode = MODE_PAN;
					winwid->mode = MODE_PAN;
				}
				else
					return;
			}
			D(("Panning\n"));
			orig_x = winwid->im_x;
			orig_y = winwid->im_y;

			winwid->im_x = ev->xmotion.x - winwid->click_offset_x;
			winwid->im_y = ev->xmotion.y - winwid->click_offset_y;

			winwidget_sanitise_offsets(winwid);

			D(("im_x %d, im_w %d, off %d, mx %d, my %d\n", winwid->im_x,
				winwid->im_w, winwid->click_offset_x, ev->xmotion.x,
				ev->xmotion.y));

			/* XWarpPointer generates a MotionNotify event which we will
			 * parse. Since that event would undo the effect of the pointer
			 * warp, we need to change the click_offset to compensate this.
			 */
			if ((winwid->w - ev->xmotion.x <= 1) && (winwid->im_x < 0))
			{
				XWarpPointer(disp, None, winwid->win, 0, 0, 0, 0, 3,
					ev->xmotion.y);
				winwid->click_offset_x -= winwid->w - 4;
			}
			// TODO needlessly warps for certain zoom levels
			else if ((ev->xmotion.x <= 1) && (winwid->im_x >
					(winwid->w - winwid->im_w * winwid->zoom)))
			{
				XWarpPointer(disp, None, winwid->win, 0, 0, 0, 0,
					winwid->w - 4, ev->xmotion.y);
				winwid->click_offset_x += winwid->w - 4;
			}
			else if ((winwid->h - ev->xmotion.y <= 1)
					&& (winwid->im_y < 0))
			{
				XWarpPointer(disp, None, winwid->win, 0, 0, 0, 0,
					ev->xmotion.x, 3);
				winwid->click_offset_y -= winwid->h - 4;
			}
			// TODO needlessly warps for certain zoomlevels
			else if ((ev->xmotion.y <= 1) && (winwid->im_y >
					(winwid->h - winwid->im_h * winwid->zoom)))
			{
				XWarpPointer(disp, None, winwid->win, 0, 0, 0, 0,
					ev->xmotion.x, winwid->h - 4);
				winwid->click_offset_y += winwid->h - 4;
			}

			if ((winwid->im_x != orig_x)
					|| (winwid->im_y != orig_y))
				winwidget_render_image(winwid, 0, 1);
		}
	} else if (opt.mode == MODE_ROTATE) {
		while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev));
		winwid = winwidget_get_from_window(ev->xmotion.window);
		if (winwid) {
			D(("Rotating\n"));
			if (!winwid->has_rotated) {
				Imlib_Image temp;

				temp = gib_imlib_create_rotated_image(winwid->im, 0.0);
				winwid->im_w = gib_imlib_image_get_width(temp);
				winwid->im_h = gib_imlib_image_get_height(temp);
				gib_imlib_free_image_and_decache(temp);
				if (!winwid->full_screen && !opt.geom_flags)
					winwidget_resize(winwid, winwid->im_w, winwid->im_h);
				winwid->has_rotated = 1;
			}
			winwid->im_angle = (ev->xmotion.x - winwid->w / 2) / ((double) winwid->w / 2) * 3.1415926535;
			D(("angle: %f\n", winwid->im_angle));
			winwidget_render_image(winwid, 0, 1);
		}
	} else if (opt.mode == MODE_BLUR) {
		while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev));
		winwid = winwidget_get_from_window(ev->xmotion.window);
		if (winwid) {
			Imlib_Image temp, ptr;
			signed int blur_radius;

			D(("Blurring\n"));

			temp = gib_imlib_clone_image(winwid->im);
			blur_radius = (((double) ev->xmotion.x / winwid->w) * 20) - 10;
			D(("angle: %d\n", blur_radius));
			if (blur_radius > 0)
				gib_imlib_image_sharpen(temp, blur_radius);
			else
				gib_imlib_image_blur(temp, 0 - blur_radius);
			ptr = winwid->im;
			winwid->im = temp;
			winwidget_render_image(winwid, 0, 1);
			gib_imlib_free_image_and_decache(winwid->im);
			winwid->im = ptr;
		}
	} else {
		while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev));
		winwid = winwidget_get_from_window(ev->xmotion.window);
		if ((winwid != NULL) && (winwid->type == WIN_TYPE_THUMBNAIL)) {
			feh_thumbnail *thumbnail;
			int x, y;

			x = (ev->xbutton.x - winwid->im_x) / winwid->zoom;
			y = (ev->xbutton.y - winwid->im_y) / winwid->zoom;
			thumbnail = feh_thumbnail_get_thumbnail_from_coords(x, y);
			feh_thumbnail_select(winwid, thumbnail);
		}
	}
	return;
}