コード例 #1
0
ファイル: events.c プロジェクト: BlackLight/feh
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;
}
コード例 #2
0
ファイル: events.c プロジェクト: BlackLight/feh
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;
}
コード例 #3
0
ファイル: events.c プロジェクト: BlackLight/feh
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;
}
コード例 #4
0
ファイル: keyevents.c プロジェクト: Ferada/feh
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;
}