mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Merge branch 'obsd-master'
This commit is contained in:
		
							
								
								
									
										82
									
								
								screen.c
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								screen.c
									
									
									
									
									
								
							@@ -47,9 +47,8 @@ struct screen_title_entry {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
TAILQ_HEAD(screen_titles, screen_title_entry);
 | 
					TAILQ_HEAD(screen_titles, screen_title_entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void	screen_resize_y(struct screen *, u_int);
 | 
					static void	screen_resize_y(struct screen *, u_int, int);
 | 
				
			||||||
 | 
					static void	screen_reflow(struct screen *, u_int, u_int *, u_int *);
 | 
				
			||||||
static void	screen_reflow(struct screen *, u_int);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Free titles stack. */
 | 
					/* Free titles stack. */
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@@ -215,10 +214,23 @@ screen_pop_title(struct screen *s)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Resize screen. */
 | 
					/* Resize screen and return cursor position. */
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
screen_resize(struct screen *s, u_int sx, u_int sy, int reflow)
 | 
					screen_resize_cursor(struct screen *s, u_int sx, u_int sy, int reflow,
 | 
				
			||||||
 | 
					    int eat_empty, u_int *cx, u_int *cy)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						u_int	tcx, tcy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cx == NULL)
 | 
				
			||||||
 | 
							cx = &tcx;
 | 
				
			||||||
 | 
						*cx = s->cx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cy == NULL)
 | 
				
			||||||
 | 
							cy = т
 | 
				
			||||||
 | 
						*cy = s->grid->hsize + s->cy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log_debug("%s: start %u,%u (%u,%u)", __func__, s->cx, s->cy, *cx, *cy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sx < 1)
 | 
						if (sx < 1)
 | 
				
			||||||
		sx = 1;
 | 
							sx = 1;
 | 
				
			||||||
	if (sy < 1)
 | 
						if (sy < 1)
 | 
				
			||||||
@@ -231,14 +243,30 @@ screen_resize(struct screen *s, u_int sx, u_int sy, int reflow)
 | 
				
			|||||||
		reflow = 0;
 | 
							reflow = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sy != screen_size_y(s))
 | 
						if (sy != screen_size_y(s))
 | 
				
			||||||
		screen_resize_y(s, sy);
 | 
							screen_resize_y(s, sy, eat_empty);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (reflow)
 | 
						if (reflow)
 | 
				
			||||||
		screen_reflow(s, sx);
 | 
							screen_reflow(s, sx, cx, cy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (*cy >= s->grid->hsize) {
 | 
				
			||||||
 | 
							s->cx = *cx;
 | 
				
			||||||
 | 
							s->cy = (*cy) - s->grid->hsize;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							s->cx = 0;
 | 
				
			||||||
 | 
							s->cy = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						log_debug("%s: finish %u,%u (%u,%u)", __func__, s->cx, s->cy, *cx, *cy);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Resize screen. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					screen_resize(struct screen *s, u_int sx, u_int sy, int reflow)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						screen_resize_cursor(s, sx, sy, reflow, 1, NULL, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
screen_resize_y(struct screen *s, u_int sy)
 | 
					screen_resize_y(struct screen *s, u_int sy, int eat_empty)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct grid	*gd = s->grid;
 | 
						struct grid	*gd = s->grid;
 | 
				
			||||||
	u_int		 needed, available, oldy, i;
 | 
						u_int		 needed, available, oldy, i;
 | 
				
			||||||
@@ -263,14 +291,16 @@ screen_resize_y(struct screen *s, u_int sy)
 | 
				
			|||||||
		needed = oldy - sy;
 | 
							needed = oldy - sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Delete as many lines as possible from the bottom. */
 | 
							/* Delete as many lines as possible from the bottom. */
 | 
				
			||||||
		available = oldy - 1 - s->cy;
 | 
							if (eat_empty) {
 | 
				
			||||||
		if (available > 0) {
 | 
								available = oldy - 1 - s->cy;
 | 
				
			||||||
			if (available > needed)
 | 
								if (available > 0) {
 | 
				
			||||||
				available = needed;
 | 
									if (available > needed)
 | 
				
			||||||
			grid_view_delete_lines(gd, oldy - available, available,
 | 
										available = needed;
 | 
				
			||||||
			    8);
 | 
									grid_view_delete_lines(gd, oldy - available,
 | 
				
			||||||
 | 
									    available, 8);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								needed -= available;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		needed -= available;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * Now just increase the history size, if possible, to take
 | 
							 * Now just increase the history size, if possible, to take
 | 
				
			||||||
@@ -286,7 +316,6 @@ screen_resize_y(struct screen *s, u_int sy)
 | 
				
			|||||||
				available = needed;
 | 
									available = needed;
 | 
				
			||||||
			grid_view_delete_lines(gd, 0, available, 8);
 | 
								grid_view_delete_lines(gd, 0, available, 8);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		s->cy -= needed;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Resize line array. */
 | 
						/* Resize line array. */
 | 
				
			||||||
@@ -306,7 +335,6 @@ screen_resize_y(struct screen *s, u_int sy)
 | 
				
			|||||||
				available = needed;
 | 
									available = needed;
 | 
				
			||||||
			gd->hscrolled -= available;
 | 
								gd->hscrolled -= available;
 | 
				
			||||||
			gd->hsize -= available;
 | 
								gd->hsize -= available;
 | 
				
			||||||
			s->cy += available;
 | 
					 | 
				
			||||||
		} else
 | 
							} else
 | 
				
			||||||
			available = 0;
 | 
								available = 0;
 | 
				
			||||||
		needed -= available;
 | 
							needed -= available;
 | 
				
			||||||
@@ -481,25 +509,17 @@ screen_select_cell(struct screen *s, struct grid_cell *dst,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* Reflow wrapped lines. */
 | 
					/* Reflow wrapped lines. */
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
screen_reflow(struct screen *s, u_int new_x)
 | 
					screen_reflow(struct screen *s, u_int new_x, u_int *cx, u_int *cy)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u_int	cx = s->cx, cy = s->grid->hsize + s->cy, wx, wy;
 | 
						u_int	wx, wy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	grid_wrap_position(s->grid, cx, cy, &wx, &wy);
 | 
						grid_wrap_position(s->grid, *cx, *cy, &wx, &wy);
 | 
				
			||||||
	log_debug("%s: cursor %u,%u is %u,%u", __func__, cx, cy, wx, wy);
 | 
						log_debug("%s: cursor %u,%u is %u,%u", __func__, *cx, *cy, wx, wy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	grid_reflow(s->grid, new_x);
 | 
						grid_reflow(s->grid, new_x);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	grid_unwrap_position(s->grid, &cx, &cy, wx, wy);
 | 
						grid_unwrap_position(s->grid, cx, cy, wx, wy);
 | 
				
			||||||
	log_debug("%s: new cursor is %u,%u", __func__, cx, cy);
 | 
						log_debug("%s: new cursor is %u,%u", __func__, *cx,* cy);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (cy >= s->grid->hsize) {
 | 
					 | 
				
			||||||
		s->cx = cx;
 | 
					 | 
				
			||||||
		s->cy = cy - s->grid->hsize;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		s->cx = 0;
 | 
					 | 
				
			||||||
		s->cy = 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								tmux.h
									
									
									
									
									
								
							@@ -2439,6 +2439,8 @@ void	 screen_set_path(struct screen *, const char *);
 | 
				
			|||||||
void	 screen_push_title(struct screen *);
 | 
					void	 screen_push_title(struct screen *);
 | 
				
			||||||
void	 screen_pop_title(struct screen *);
 | 
					void	 screen_pop_title(struct screen *);
 | 
				
			||||||
void	 screen_resize(struct screen *, u_int, u_int, int);
 | 
					void	 screen_resize(struct screen *, u_int, u_int, int);
 | 
				
			||||||
 | 
					void	 screen_resize_cursor(struct screen *, u_int, u_int, int, int, u_int *,
 | 
				
			||||||
 | 
						     u_int *);
 | 
				
			||||||
void	 screen_set_selection(struct screen *, u_int, u_int, u_int, u_int,
 | 
					void	 screen_set_selection(struct screen *, u_int, u_int, u_int, u_int,
 | 
				
			||||||
	     u_int, int, struct grid_cell *);
 | 
						     u_int, int, struct grid_cell *);
 | 
				
			||||||
void	 screen_clear_selection(struct screen *);
 | 
					void	 screen_clear_selection(struct screen *);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -298,30 +298,33 @@ window_copy_scroll_timer(__unused int fd, __unused short events, void *arg)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct screen *
 | 
					static struct screen *
 | 
				
			||||||
window_copy_clone_screen(struct screen *src, struct screen *hint)
 | 
					window_copy_clone_screen(struct screen *src, struct screen *hint, u_int *cx,
 | 
				
			||||||
 | 
					    u_int *cy)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct screen			*dst;
 | 
						struct screen		*dst;
 | 
				
			||||||
	struct screen_write_ctx		 ctx;
 | 
						u_int			 sy;
 | 
				
			||||||
	u_int				 dy, sy;
 | 
						const struct grid_line	*gl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dst = xcalloc(1, sizeof *dst);
 | 
						dst = xcalloc(1, sizeof *dst);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sy = screen_hsize(src) + screen_size_y(src);
 | 
						sy = screen_hsize(src) + screen_size_y(src);
 | 
				
			||||||
	if (screen_size_y(hint) > sy)
 | 
						while (sy > screen_hsize(src)) {
 | 
				
			||||||
		dy = screen_size_y(hint);
 | 
							gl = grid_peek_line(src->grid, sy - 1);
 | 
				
			||||||
	else
 | 
							if (gl->cellused != 0)
 | 
				
			||||||
		dy = sy;
 | 
								break;
 | 
				
			||||||
	screen_init(dst, screen_size_x(src), dy, src->grid->hlimit);
 | 
							sy--;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	grid_duplicate_lines(dst->grid, 0, src->grid, 0, sy);
 | 
					 | 
				
			||||||
	if (screen_size_y(hint) < sy) {
 | 
					 | 
				
			||||||
		dst->grid->sy = screen_size_y(hint);
 | 
					 | 
				
			||||||
		dst->grid->hsize = sy - screen_size_y(hint);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						screen_init(dst, screen_size_x(src), sy, screen_hlimit(src));
 | 
				
			||||||
 | 
						grid_duplicate_lines(dst->grid, 0, src->grid, 0, sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	screen_write_start(&ctx, NULL, dst);
 | 
						dst->grid->sy = sy - screen_hsize(src);
 | 
				
			||||||
	screen_write_cursormove(&ctx, 0, dst->grid->sy + sy - dy - 1, 0);
 | 
						dst->grid->hsize = screen_hsize(src);
 | 
				
			||||||
	screen_write_stop(&ctx);
 | 
						dst->grid->hscrolled = src->grid->hscrolled;
 | 
				
			||||||
 | 
						dst->cx = src->cx;
 | 
				
			||||||
 | 
						dst->cy = src->cy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						screen_resize_cursor(dst, screen_size_x(hint), screen_size_y(hint), 1,
 | 
				
			||||||
 | 
						    0, cx, cy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (dst);
 | 
						return (dst);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -370,22 +373,22 @@ window_copy_init(struct window_mode_entry *wme,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	struct window_pane		*wp = wme->swp;
 | 
						struct window_pane		*wp = wme->swp;
 | 
				
			||||||
	struct window_copy_mode_data	*data;
 | 
						struct window_copy_mode_data	*data;
 | 
				
			||||||
 | 
						struct screen			*base = &wp->base;
 | 
				
			||||||
	struct screen_write_ctx		 ctx;
 | 
						struct screen_write_ctx		 ctx;
 | 
				
			||||||
	u_int				 i;
 | 
						u_int				 i, cx, cy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data = window_copy_common_init(wme);
 | 
						data = window_copy_common_init(wme);
 | 
				
			||||||
	data->backing = window_copy_clone_screen(&wp->base, &data->screen);
 | 
						data->backing = window_copy_clone_screen(base, &data->screen, &cx, &cy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data->cx = wp->base.cx;
 | 
						if (cy < screen_hsize(data->backing)) {
 | 
				
			||||||
	if (data->cx > screen_size_x(&data->screen) - 1)
 | 
							data->cx = cx;
 | 
				
			||||||
		data->cx = screen_size_x(&data->screen) - 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	data->cy = screen_hsize(&wp->base) + wp->base.cy;
 | 
					 | 
				
			||||||
	if (data->cy < screen_hsize(data->backing)) {
 | 
					 | 
				
			||||||
		data->oy = screen_hsize(data->backing) - data->cy;
 | 
					 | 
				
			||||||
		data->cy = 0;
 | 
							data->cy = 0;
 | 
				
			||||||
	} else
 | 
							data->oy = screen_hsize(data->backing) - cy;
 | 
				
			||||||
		data->cy -= screen_hsize(data->backing);
 | 
						} else {
 | 
				
			||||||
 | 
							data->cx = data->backing->cx;
 | 
				
			||||||
 | 
							data->cy = data->backing->cy;
 | 
				
			||||||
 | 
							data->oy = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data->scroll_exit = args_has(args, 'e');
 | 
						data->scroll_exit = args_has(args, 'e');
 | 
				
			||||||
	data->hide_position = args_has(args, 'H');
 | 
						data->hide_position = args_has(args, 'H');
 | 
				
			||||||
@@ -697,8 +700,8 @@ window_copy_resize(struct window_mode_entry *wme, u_int sx, u_int sy)
 | 
				
			|||||||
	struct screen_write_ctx	 	 ctx;
 | 
						struct screen_write_ctx	 	 ctx;
 | 
				
			||||||
	int				 search;
 | 
						int				 search;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	screen_resize(s, sx, sy, 1);
 | 
						screen_resize(s, sx, sy, 0);
 | 
				
			||||||
	screen_resize(data->backing, sx, sy, 1);
 | 
						screen_resize_cursor(data->backing, sx, sy, 1, 0, NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (data->cy > sy - 1)
 | 
						if (data->cy > sy - 1)
 | 
				
			||||||
		data->cy = sy - 1;
 | 
							data->cy = sy - 1;
 | 
				
			||||||
@@ -2024,7 +2027,8 @@ window_copy_cmd_refresh_from_pane(struct window_copy_cmd_state *cs)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	screen_free(data->backing);
 | 
						screen_free(data->backing);
 | 
				
			||||||
	free(data->backing);
 | 
						free(data->backing);
 | 
				
			||||||
	data->backing = window_copy_clone_screen(&wp->base, &data->screen);
 | 
						data->backing = window_copy_clone_screen(&wp->base, &data->screen, NULL,
 | 
				
			||||||
 | 
						    NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (WINDOW_COPY_CMD_REDRAW);
 | 
						return (WINDOW_COPY_CMD_REDRAW);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user