diff --git a/grid-reader.c b/grid-reader.c
index a1af3aaa..c011ea1d 100644
--- a/grid-reader.c
+++ b/grid-reader.c
@@ -17,6 +17,7 @@
  */
 
 #include "tmux.h"
+#include <string.h>
 
 /* Initialise virtual cursor. */
 void
@@ -301,3 +302,64 @@ grid_reader_cursor_previous_word(struct grid_reader *gr, const char *separators,
 	gr->cx = oldx;
 	gr->cy = oldy;
 }
+
+/* Jump forward to character. */
+int
+grid_reader_cursor_jump(struct grid_reader *gr, const struct utf8_data *jc)
+{
+	struct grid_cell	gc;
+	u_int			px, py, xx, yy;
+
+	px = gr->cx;
+	yy = gr->gd->hsize + gr->gd->sy - 1;
+
+	for (py = gr->cy; py <= yy; py++) {
+		xx = grid_line_length(gr->gd, py);
+		while (px < xx) {
+			grid_get_cell(gr->gd, px, py, &gc);
+			if (!(gc.flags & GRID_FLAG_PADDING) &&
+			    gc.data.size == jc->size &&
+			    memcmp(gc.data.data, jc->data, gc.data.size) == 0) {
+				gr->cx = px;
+				gr->cy = py;
+				return 1;
+			}
+			px++;
+		}
+
+		if (py == yy ||
+		    !(grid_get_line(gr->gd, py)->flags & GRID_LINE_WRAPPED))
+			return 0;
+		px = 0;
+	}
+	return 0;
+}
+
+/* Jump back to character. */
+int
+grid_reader_cursor_jump_back(struct grid_reader *gr, const struct utf8_data *jc)
+{
+	struct grid_cell	gc;
+	u_int			px, py, xx;
+
+	xx = gr->cx + 1;
+
+	for (py = gr->cy + 1; py > 0; py--) {
+		for (px = xx; px > 0; px--) {
+			grid_get_cell(gr->gd, px - 1, py - 1, &gc);
+			if (!(gc.flags & GRID_FLAG_PADDING) &&
+			    gc.data.size == jc->size &&
+			    memcmp(gc.data.data, jc->data, gc.data.size) == 0) {
+				gr->cx = px - 1;
+				gr->cy = py - 1;
+				return 1;
+			}
+		}
+
+		if (py == 1 ||
+		    !(grid_get_line(gr->gd, py - 2)->flags & GRID_LINE_WRAPPED))
+			return 0;
+		xx = grid_line_length(gr->gd, py - 2);
+	}
+	return 0;
+}
diff --git a/status.c b/status.c
index 82107c58..154d9452 100644
--- a/status.c
+++ b/status.c
@@ -1319,12 +1319,14 @@ append_key:
 	}
 
 	if (c->prompt_flags & PROMPT_SINGLE) {
-		s = utf8_tocstr(c->prompt_buffer);
-		if (strlen(s) != 1)
+		if (utf8_strlen(c->prompt_buffer) != 1)
 			status_prompt_clear(c);
-		else if (c->prompt_inputcb(c, c->prompt_data, s, 1) == 0)
-			status_prompt_clear(c);
-		free(s);
+		else {
+			s = utf8_tocstr(c->prompt_buffer);
+			if (c->prompt_inputcb(c, c->prompt_data, s, 1) == 0)
+				status_prompt_clear(c);
+			free(s);
+		}
 	}
 
 changed:
diff --git a/tmux.h b/tmux.h
index 88c6d30e..4339f6a7 100644
--- a/tmux.h
+++ b/tmux.h
@@ -2589,6 +2589,10 @@ void	 grid_reader_cursor_next_word(struct grid_reader *, const char *);
 void	 grid_reader_cursor_next_word_end(struct grid_reader *, const char *);
 void	 grid_reader_cursor_previous_word(struct grid_reader *, const char *,
 	     int);
+int	 grid_reader_cursor_jump(struct grid_reader *,
+	     const struct utf8_data *);
+int	 grid_reader_cursor_jump_back(struct grid_reader *,
+	     const struct utf8_data *);
 
 /* grid-view.c */
 void	 grid_view_get_cell(struct grid *, u_int, u_int, struct grid_cell *);
diff --git a/window-copy.c b/window-copy.c
index c6b25413..af8d2937 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -135,6 +135,10 @@ static void	window_copy_move_mouse(struct mouse_event *);
 static void	window_copy_drag_update(struct client *, struct mouse_event *);
 static void	window_copy_drag_release(struct client *, struct mouse_event *);
 static void	window_copy_jump_to_mark(struct window_mode_entry *);
+static void	window_copy_acquire_cursor_up(struct window_mode_entry *,
+		    u_int, u_int, u_int, u_int, u_int);
+static void	window_copy_acquire_cursor_down(struct window_mode_entry *,
+		    u_int, u_int, u_int, u_int, u_int, u_int, int);
 
 const struct window_mode window_copy_mode = {
 	.name = "copy-mode",
@@ -284,8 +288,8 @@ struct window_copy_mode_data {
 #define WINDOW_COPY_SEARCH_TIMEOUT 10000
 #define WINDOW_COPY_SEARCH_ALL_TIMEOUT 200
 
-	int		 jumptype;
-	char		 jumpchar;
+	int			 jumptype;
+	struct utf8_data	*jumpchar;
 
 	struct event	 dragtimer;
 #define WINDOW_COPY_DRAG_REPEAT_TIME 50000
@@ -401,7 +405,7 @@ window_copy_common_init(struct window_mode_entry *wme)
 	data->searchall = 1;
 
 	data->jumptype = WINDOW_COPY_OFF;
-	data->jumpchar = '\0';
+	data->jumpchar = NULL;
 
 	screen_init(&data->screen, screen_size_x(base), screen_size_y(base), 0);
 	data->modekeys = options_get_number(wp->window->options, "mode-keys");
@@ -482,6 +486,7 @@ window_copy_free(struct window_mode_entry *wme)
 
 	free(data->searchmark);
 	free(data->searchstr);
+	free(data->jumpchar);
 
 	screen_free(data->backing);
 	free(data->backing);
@@ -1935,7 +1940,8 @@ window_copy_cmd_jump_backward(struct window_copy_cmd_state *cs)
 
 	if (*argument != '\0') {
 		data->jumptype = WINDOW_COPY_JUMPBACKWARD;
-		data->jumpchar = *argument;
+		free(data->jumpchar);
+		data->jumpchar = utf8_fromcstr(argument);
 		for (; np != 0; np--)
 			window_copy_cursor_jump_back(wme);
 	}
@@ -1952,7 +1958,8 @@ window_copy_cmd_jump_forward(struct window_copy_cmd_state *cs)
 
 	if (*argument != '\0') {
 		data->jumptype = WINDOW_COPY_JUMPFORWARD;
-		data->jumpchar = *argument;
+		free(data->jumpchar);
+		data->jumpchar = utf8_fromcstr(argument);
 		for (; np != 0; np--)
 			window_copy_cursor_jump(wme);
 	}
@@ -1969,7 +1976,8 @@ window_copy_cmd_jump_to_backward(struct window_copy_cmd_state *cs)
 
 	if (*argument != '\0') {
 		data->jumptype = WINDOW_COPY_JUMPTOBACKWARD;
-		data->jumpchar = *argument;
+		free(data->jumpchar);
+		data->jumpchar = utf8_fromcstr(argument);
 		for (; np != 0; np--)
 			window_copy_cursor_jump_to_back(wme);
 	}
@@ -1986,7 +1994,8 @@ window_copy_cmd_jump_to_forward(struct window_copy_cmd_state *cs)
 
 	if (*argument != '\0') {
 		data->jumptype = WINDOW_COPY_JUMPTOFORWARD;
-		data->jumpchar = *argument;
+		free(data->jumpchar);
+		data->jumpchar = utf8_fromcstr(argument);
 		for (; np != 0; np--)
 			window_copy_cursor_jump_to(wme);
 	}
@@ -4074,7 +4083,7 @@ window_copy_cursor_start_of_line(struct window_mode_entry *wme)
 	struct window_copy_mode_data	*data = wme->data;
 	struct screen			*back_s = data->backing;
 	struct grid_reader		 gr;
-	u_int				 px, py, cy, oldy, yy, ny, nd, hsize;
+	u_int				 px, py, oldy, hsize;
 
 	px = data->cx;
 	hsize = screen_hsize(back_s);
@@ -4084,25 +4093,7 @@ window_copy_cursor_start_of_line(struct window_mode_entry *wme)
 	grid_reader_start(&gr, back_s->grid, px, py);
 	grid_reader_cursor_start_of_line(&gr, 1);
 	grid_reader_get_cursor(&gr, &px, &py);
-
-	/* Scroll up if we went off the visible screen. */
-	yy = hsize - data->oy;
-	if (py < yy) {
-		ny = yy - py;
-		cy = 0;
-		nd = 1;
-	} else {
-		ny = 0;
-		cy = py - yy;
-		nd = oldy - cy + 1;
-	}
-	while (ny > 0) {
-		window_copy_cursor_up(wme, 1);
-		ny--;
-	}
-	window_copy_update_cursor(wme, px, cy);
-	if (window_copy_update_selection(wme, 1, 0))
-		window_copy_redraw_lines(wme, data->cy, nd);
+	window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, px, py);
 }
 
 static void
@@ -4134,7 +4125,7 @@ window_copy_cursor_end_of_line(struct window_mode_entry *wme)
 	struct window_copy_mode_data	*data = wme->data;
 	struct screen			*back_s = data->backing;
 	struct grid_reader		 gr;
-	u_int				 px, py, cy, oldy, yy, ny, nd, hsize;
+	u_int				 px, py, oldy, hsize;
 
 	px = data->cx;
 	hsize = screen_hsize(back_s);
@@ -4147,28 +4138,8 @@ window_copy_cursor_end_of_line(struct window_mode_entry *wme)
 	else
 		grid_reader_cursor_end_of_line(&gr, 1, 0);
 	grid_reader_get_cursor(&gr, &px, &py);
-
-	/* Scroll down if we went off the visible screen. */
-	cy = py - hsize + data->oy;
-	yy = screen_size_y(back_s) - 1;
-	if (cy > yy) {
-		ny = cy - yy;
-		oldy = yy;
-		nd = 1;
-	} else {
-		ny = 0;
-		nd = cy - oldy + 1;
-	}
-	while (ny > 0) {
-	  window_copy_cursor_down(wme, 1);
-	  ny--;
-	}
-	if (cy > yy)
-		window_copy_update_cursor(wme, px, yy);
-	else
-		window_copy_update_cursor(wme, px, cy);
-	if (window_copy_update_selection(wme, 1, 0))
-		window_copy_redraw_lines(wme, oldy, nd);
+	window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s),
+	    data->oy, oldy, px, py, 0);
 }
 
 static void
@@ -4228,32 +4199,17 @@ window_copy_cursor_left(struct window_mode_entry *wme)
 	struct window_copy_mode_data	*data = wme->data;
 	struct screen			*back_s = data->backing;
 	struct grid_reader		 gr;
-	u_int				 px, py, cy, yy, ny, hsize;
+	u_int				 px, py, oldy, hsize;
 
 	px = data->cx;
 	hsize = screen_hsize(back_s);
 	py = hsize + data->cy - data->oy;
+	oldy = data->cy;
 
 	grid_reader_start(&gr, back_s->grid, px, py);
 	grid_reader_cursor_left(&gr);
 	grid_reader_get_cursor(&gr, &px, &py);
-
-	/* Scroll up if we went off the visible screen. */
-	yy = hsize - data->oy;
-	if (py < yy) {
-		ny = yy - py;
-		cy = 0;
-	} else {
-		ny = 0;
-		cy = py - yy;
-	}
-	while (ny > 0) {
-		window_copy_cursor_up(wme, 1);
-		ny--;
-	}
-	window_copy_update_cursor(wme, px, cy);
-	if (window_copy_update_selection(wme, 1, 0))
-		window_copy_redraw_lines(wme, data->cy, 1);
+	window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, px, py);
 }
 
 static void
@@ -4262,33 +4218,18 @@ window_copy_cursor_right(struct window_mode_entry *wme, int all)
 	struct window_copy_mode_data	*data = wme->data;
 	struct screen			*back_s = data->backing;
 	struct grid_reader		 gr;
-	u_int				 px, py, cy, yy, ny, hsize;
+	u_int				 px, py, oldy, hsize;
 
 	px = data->cx;
 	hsize = screen_hsize(back_s);
 	py = hsize + data->cy - data->oy;
+	oldy = data->cy;
 
 	grid_reader_start(&gr, back_s->grid, px, py);
 	grid_reader_cursor_right(&gr, 1, all);
 	grid_reader_get_cursor(&gr, &px, &py);
-
-	/* Scroll down if we went off the visible screen. */
-	cy = py - hsize + data->oy;
-	yy = screen_size_y(back_s) - 1;
-	if (cy > yy)
-		ny = cy - yy;
-	else
-		ny = 0;
-	while (ny > 0) {
-	  window_copy_cursor_down(wme, 1);
-	  ny--;
-	}
-	if (cy > yy)
-		window_copy_update_cursor(wme, px, yy);
-	else
-		window_copy_update_cursor(wme, px, cy);
-	if (window_copy_update_selection(wme, 1, 0))
-		window_copy_redraw_lines(wme, data->cy, 1);
+	window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s),
+	    data->oy, oldy, px, py, 0);
 }
 
 static void
@@ -4422,23 +4363,19 @@ window_copy_cursor_jump(struct window_mode_entry *wme)
 {
 	struct window_copy_mode_data	*data = wme->data;
 	struct screen			*back_s = data->backing;
-	struct grid_cell		 gc;
-	u_int				 px, py, xx;
+	struct grid_reader		 gr;
+	u_int				 px, py, oldy, hsize;
 
 	px = data->cx + 1;
-	py = screen_hsize(back_s) + data->cy - data->oy;
-	xx = window_copy_find_length(wme, py);
+	hsize = screen_hsize(back_s);
+	py = hsize + data->cy - data->oy;
+	oldy = data->cy;
 
-	while (px < xx) {
-		grid_get_cell(back_s->grid, px, py, &gc);
-		if (!(gc.flags & GRID_FLAG_PADDING) &&
-		    gc.data.size == 1 && *gc.data.data == data->jumpchar) {
-			window_copy_update_cursor(wme, px, data->cy);
-			if (window_copy_update_selection(wme, 1, 0))
-				window_copy_redraw_lines(wme, data->cy, 1);
-			return;
-		}
-		px++;
+	grid_reader_start(&gr, back_s->grid, px, py);
+	if (grid_reader_cursor_jump(&gr, data->jumpchar)) {
+		grid_reader_get_cursor(&gr, &px, &py);
+		window_copy_acquire_cursor_down(wme, hsize,
+		    screen_size_y(back_s), data->oy, oldy, px, py, 0);
 	}
 }
 
@@ -4447,27 +4384,22 @@ window_copy_cursor_jump_back(struct window_mode_entry *wme)
 {
 	struct window_copy_mode_data	*data = wme->data;
 	struct screen			*back_s = data->backing;
-	struct grid_cell		 gc;
-	u_int				 px, py;
+	struct grid_reader		 gr;
+	u_int				 px, py, oldy, hsize;
 
 	px = data->cx;
-	py = screen_hsize(back_s) + data->cy - data->oy;
+	hsize = screen_hsize(back_s);
+	py = hsize + data->cy - data->oy;
+	oldy = data->cy;
 
 	if (px > 0)
 		px--;
 
-	for (;;) {
-		grid_get_cell(back_s->grid, px, py, &gc);
-		if (!(gc.flags & GRID_FLAG_PADDING) &&
-		    gc.data.size == 1 && *gc.data.data == data->jumpchar) {
-			window_copy_update_cursor(wme, px, data->cy);
-			if (window_copy_update_selection(wme, 1, 0))
-				window_copy_redraw_lines(wme, data->cy, 1);
-			return;
-		}
-		if (px == 0)
-			break;
-		px--;
+	grid_reader_start(&gr, back_s->grid, px, py);
+	if (grid_reader_cursor_jump_back(&gr, data->jumpchar)) {
+		grid_reader_get_cursor(&gr, &px, &py);
+		window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, px,
+		    py);
 	}
 }
 
@@ -4476,23 +4408,20 @@ window_copy_cursor_jump_to(struct window_mode_entry *wme)
 {
 	struct window_copy_mode_data	*data = wme->data;
 	struct screen			*back_s = data->backing;
-	struct grid_cell		 gc;
-	u_int				 px, py, xx;
+	struct grid_reader		 gr;
+	u_int				 px, py, oldy, hsize;
 
 	px = data->cx + 2;
-	py = screen_hsize(back_s) + data->cy - data->oy;
-	xx = window_copy_find_length(wme, py);
+	hsize = screen_hsize(back_s);
+	py = hsize + data->cy - data->oy;
+	oldy = data->cy;
 
-	while (px < xx) {
-		grid_get_cell(back_s->grid, px, py, &gc);
-		if (!(gc.flags & GRID_FLAG_PADDING) &&
-		    gc.data.size == 1 && *gc.data.data == data->jumpchar) {
-			window_copy_update_cursor(wme, px - 1, data->cy);
-			if (window_copy_update_selection(wme, 1, 0))
-				window_copy_redraw_lines(wme, data->cy, 1);
-			return;
-		}
-		px++;
+	grid_reader_start(&gr, back_s->grid, px, py);
+	if (grid_reader_cursor_jump(&gr, data->jumpchar)) {
+		grid_reader_cursor_left(&gr);
+		grid_reader_get_cursor(&gr, &px, &py);
+		window_copy_acquire_cursor_down(wme, hsize,
+		    screen_size_y(back_s), data->oy, oldy, px, py, 0);
 	}
 }
 
@@ -4501,11 +4430,13 @@ window_copy_cursor_jump_to_back(struct window_mode_entry *wme)
 {
 	struct window_copy_mode_data	*data = wme->data;
 	struct screen			*back_s = data->backing;
-	struct grid_cell		 gc;
-	u_int				 px, py;
+	struct grid_reader		 gr;
+	u_int				 px, py, oldy, hsize;
 
 	px = data->cx;
-	py = screen_hsize(back_s) + data->cy - data->oy;
+	hsize = screen_hsize(back_s);
+	py = hsize + data->cy - data->oy;
+	oldy = data->cy;
 
 	if (px > 0)
 		px--;
@@ -4513,18 +4444,12 @@ window_copy_cursor_jump_to_back(struct window_mode_entry *wme)
 	if (px > 0)
 		px--;
 
-	for (;;) {
-		grid_get_cell(back_s->grid, px, py, &gc);
-		if (!(gc.flags & GRID_FLAG_PADDING) &&
-		    gc.data.size == 1 && *gc.data.data == data->jumpchar) {
-			window_copy_update_cursor(wme, px + 1, data->cy);
-			if (window_copy_update_selection(wme, 1, 0))
-				window_copy_redraw_lines(wme, data->cy, 1);
-			return;
-		}
-		if (px == 0)
-			break;
-		px--;
+	grid_reader_start(&gr, back_s->grid, px, py);
+	if (grid_reader_cursor_jump_back(&gr, data->jumpchar)) {
+		grid_reader_cursor_right(&gr, 1, 0);
+		grid_reader_get_cursor(&gr, &px, &py);
+		window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, px,
+		    py);
 	}
 }
 
@@ -4535,7 +4460,7 @@ window_copy_cursor_next_word(struct window_mode_entry *wme,
 	struct window_copy_mode_data	*data = wme->data;
 	struct screen			*back_s = data->backing;
 	struct grid_reader		 gr;
-	u_int				 px, py, cy, oldy, yy, ny, nd, hsize;
+	u_int				 px, py, oldy, hsize;
 
 	px = data->cx;
 	hsize = screen_hsize(back_s);
@@ -4545,28 +4470,8 @@ window_copy_cursor_next_word(struct window_mode_entry *wme,
 	grid_reader_start(&gr, back_s->grid, px, py);
 	grid_reader_cursor_next_word(&gr, separators);
 	grid_reader_get_cursor(&gr, &px, &py);
-
-	/* Scroll down if we went off the visible screen. */
-	cy = py - hsize + data->oy;
-	yy = screen_size_y(back_s) - 1;
-	if (cy > yy) {
-		ny = cy - yy;
-		oldy = yy;
-		nd = 1;
-	} else {
-		ny = 0;
-		nd = cy - oldy + 1;
-	}
-	while (ny > 0) {
-	  window_copy_cursor_down(wme, 1);
-	  ny--;
-	}
-	if (cy > yy)
-		window_copy_update_cursor(wme, px, yy);
-	else
-		window_copy_update_cursor(wme, px, cy);
-	if (window_copy_update_selection(wme, 1, 0))
-		window_copy_redraw_lines(wme, oldy, nd);
+	window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s),
+	    data->oy, oldy, px, py, 0);
 }
 
 static void
@@ -4627,7 +4532,7 @@ window_copy_cursor_next_word_end(struct window_mode_entry *wme,
 	struct options			*oo = wp->window->options;
 	struct screen			*back_s = data->backing;
 	struct grid_reader		 gr;
-	u_int				 px, py, cy, oldy, yy, ny, nd, hsize;
+	u_int				 px, py, oldy, hsize;
 	int				 keys;
 
 	px = data->cx;
@@ -4643,28 +4548,8 @@ window_copy_cursor_next_word_end(struct window_mode_entry *wme,
 	if (keys == MODEKEY_VI)
 		grid_reader_cursor_left(&gr);
 	grid_reader_get_cursor(&gr, &px, &py);
-
-	/* Scroll down if we went off the visible screen. */
-	cy = py - hsize + data->oy;
-	yy = screen_size_y(back_s) - 1;
-	if (cy > yy) {
-		ny = cy - yy;
-		oldy = yy;
-		nd = 1;
-	} else {
-		ny = 0;
-		nd = cy - oldy + 1;
-	}
-	while (ny > 0) {
-	  window_copy_cursor_down(wme, 1);
-	  ny--;
-	}
-	if (cy > yy)
-		window_copy_update_cursor(wme, px, yy);
-	else
-		window_copy_update_cursor(wme, px, cy);
-	if (window_copy_update_selection(wme, 1, no_reset))
-		window_copy_redraw_lines(wme, oldy, nd);
+	window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s),
+	    data->oy, oldy, px, py, no_reset);
 }
 
 /* Compute the previous place where a word begins. */
@@ -4721,7 +4606,7 @@ window_copy_cursor_previous_word(struct window_mode_entry *wme,
 	struct window_copy_mode_data	*data = wme->data;
 	struct screen			*back_s = data->backing;
 	struct grid_reader		 gr;
-	u_int				 px, py, cy, oldy, yy, ny, nd, hsize;
+	u_int				 px, py, oldy, hsize;
 
 	px = data->cx;
 	hsize = screen_hsize(back_s);
@@ -4731,25 +4616,7 @@ window_copy_cursor_previous_word(struct window_mode_entry *wme,
 	grid_reader_start(&gr, back_s->grid, px, py);
 	grid_reader_cursor_previous_word(&gr, separators, already);
 	grid_reader_get_cursor(&gr, &px, &py);
-
-	/* Scroll up if we went off the visible screen. */
-	yy = hsize - data->oy;
-	if (py < yy) {
-		ny = yy - py;
-		cy = 0;
-		nd = 1;
-	} else {
-		ny = 0;
-		cy = py - yy;
-		nd = oldy - cy + 1;
-	}
-	while (ny > 0) {
-		window_copy_cursor_up(wme, 1);
-		ny--;
-	}
-	window_copy_update_cursor(wme, px, cy);
-	if (window_copy_update_selection(wme, 1, 0))
-		window_copy_redraw_lines(wme, data->cy, nd);
+	window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, px, py);
 }
 
 static void
@@ -5000,3 +4867,58 @@ window_copy_jump_to_mark(struct window_mode_entry *wme)
 	window_copy_update_selection(wme, 0, 0);
 	window_copy_redraw_screen(wme);
 }
+
+/* Scroll up if the cursor went off the visible screen. */
+static void
+window_copy_acquire_cursor_up(struct window_mode_entry *wme, u_int hsize,
+    u_int oy, u_int oldy, u_int px, u_int py)
+{
+	u_int	cy, yy, ny, nd;
+
+	yy = hsize - oy;
+	if (py < yy) {
+		ny = yy - py;
+		cy = 0;
+		nd = 1;
+	} else {
+		ny = 0;
+		cy = py - yy;
+		nd = oldy - cy + 1;
+	}
+	while (ny > 0) {
+		window_copy_cursor_up(wme, 1);
+		ny--;
+	}
+	window_copy_update_cursor(wme, px, cy);
+	if (window_copy_update_selection(wme, 1, 0))
+		window_copy_redraw_lines(wme, cy, nd);
+}
+
+/* Scroll down if the cursor went off the visible screen. */
+static void
+window_copy_acquire_cursor_down(struct window_mode_entry *wme, u_int hsize,
+    u_int sy, u_int oy, u_int oldy, u_int px, u_int py, int no_reset)
+{
+	u_int	cy, yy, ny, nd;
+
+	cy = py - hsize + oy;
+	yy = sy - 1;
+	if (cy > yy) {
+		ny = cy - yy;
+		oldy = yy;
+		nd = 1;
+	} else {
+		ny = 0;
+		nd = cy - oldy + 1;
+	}
+	while (ny > 0) {
+	  window_copy_cursor_down(wme, 1);
+	  ny--;
+	}
+	if (cy > yy)
+		window_copy_update_cursor(wme, px, yy);
+	else
+		window_copy_update_cursor(wme, px, cy);
+	if (window_copy_update_selection(wme, 1, no_reset))
+		window_copy_redraw_lines(wme, oldy, nd);
+}