xref: /openbsd-src/usr.bin/tmux/grid-view.c (revision 32b2c715e7efe88128f64e4eebf2ef2475ee6eb9)
1*32b2c715Snicm /* $OpenBSD: grid-view.c,v 1.36 2022/09/28 07:55:29 nicm Exp $ */
2311827fbSnicm 
3311827fbSnicm /*
498ca8272Snicm  * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
5311827fbSnicm  *
6311827fbSnicm  * Permission to use, copy, modify, and distribute this software for any
7311827fbSnicm  * purpose with or without fee is hereby granted, provided that the above
8311827fbSnicm  * copyright notice and this permission notice appear in all copies.
9311827fbSnicm  *
10311827fbSnicm  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11311827fbSnicm  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12311827fbSnicm  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13311827fbSnicm  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14311827fbSnicm  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15311827fbSnicm  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16311827fbSnicm  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17311827fbSnicm  */
18311827fbSnicm 
19311827fbSnicm #include <sys/types.h>
20311827fbSnicm 
21311827fbSnicm #include <string.h>
22311827fbSnicm 
23311827fbSnicm #include "tmux.h"
24311827fbSnicm 
25311827fbSnicm /*
26311827fbSnicm  * Grid view functions. These work using coordinates relative to the visible
27311827fbSnicm  * screen area.
28311827fbSnicm  */
29311827fbSnicm 
30311827fbSnicm #define grid_view_x(gd, x) (x)
31311827fbSnicm #define grid_view_y(gd, y) ((gd)->hsize + (y))
32311827fbSnicm 
3306e95881Snicm /* Get cell. */
34e931849fSnicm void
grid_view_get_cell(struct grid * gd,u_int px,u_int py,struct grid_cell * gc)35e931849fSnicm grid_view_get_cell(struct grid *gd, u_int px, u_int py, struct grid_cell *gc)
36311827fbSnicm {
37e931849fSnicm 	grid_get_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py), gc);
38311827fbSnicm }
39311827fbSnicm 
40311827fbSnicm /* Set cell. */
41311827fbSnicm void
grid_view_set_cell(struct grid * gd,u_int px,u_int py,const struct grid_cell * gc)42e931849fSnicm grid_view_set_cell(struct grid *gd, u_int px, u_int py,
43e931849fSnicm     const struct grid_cell *gc)
44311827fbSnicm {
45311827fbSnicm 	grid_set_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py), gc);
46311827fbSnicm }
47311827fbSnicm 
4871a06389Snicm /* Set padding. */
4971a06389Snicm void
grid_view_set_padding(struct grid * gd,u_int px,u_int py)5071a06389Snicm grid_view_set_padding(struct grid *gd, u_int px, u_int py)
5171a06389Snicm {
5271a06389Snicm 	grid_set_padding(gd, grid_view_x(gd, px), grid_view_y(gd, py));
5371a06389Snicm }
5471a06389Snicm 
558248eab7Snicm /* Set cells. */
568248eab7Snicm void
grid_view_set_cells(struct grid * gd,u_int px,u_int py,const struct grid_cell * gc,const char * s,size_t slen)578248eab7Snicm grid_view_set_cells(struct grid *gd, u_int px, u_int py,
588248eab7Snicm     const struct grid_cell *gc, const char *s, size_t slen)
598248eab7Snicm {
608248eab7Snicm 	grid_set_cells(gd, grid_view_x(gd, px), grid_view_y(gd, py), gc, s,
618248eab7Snicm 	    slen);
628248eab7Snicm }
638248eab7Snicm 
640864dd21Snicm /* Clear into history. */
650864dd21Snicm void
grid_view_clear_history(struct grid * gd,u_int bg)66ae4624e7Snicm grid_view_clear_history(struct grid *gd, u_int bg)
670864dd21Snicm {
680864dd21Snicm 	struct grid_line	*gl;
690864dd21Snicm 	u_int			 yy, last;
700864dd21Snicm 
710864dd21Snicm 	/* Find the last used line. */
720864dd21Snicm 	last = 0;
730864dd21Snicm 	for (yy = 0; yy < gd->sy; yy++) {
747621e88fSnicm 		gl = grid_get_line(gd, grid_view_y(gd, yy));
75ae4624e7Snicm 		if (gl->cellused != 0)
760864dd21Snicm 			last = yy + 1;
770864dd21Snicm 	}
78ae4624e7Snicm 	if (last == 0) {
79ae4624e7Snicm 		grid_view_clear(gd, 0, 0, gd->sx, gd->sy, bg);
800864dd21Snicm 		return;
81ae4624e7Snicm 	}
820864dd21Snicm 
830864dd21Snicm 	/* Scroll the lines into the history. */
841073c1c1Snicm 	for (yy = 0; yy < last; yy++) {
85bd28ed35Snicm 		grid_collect_history(gd);
86ae4624e7Snicm 		grid_scroll_history(gd, bg);
870864dd21Snicm 	}
88ae4624e7Snicm 	if (last < gd->sy)
89ae4624e7Snicm 		grid_view_clear(gd, 0, 0, gd->sx, gd->sy - last, bg);
9093ccd604Snicm 	gd->hscrolled = 0;
911073c1c1Snicm }
920864dd21Snicm 
93311827fbSnicm /* Clear area. */
94311827fbSnicm void
grid_view_clear(struct grid * gd,u_int px,u_int py,u_int nx,u_int ny,u_int bg)95ae4624e7Snicm grid_view_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny,
96ae4624e7Snicm     u_int bg)
97311827fbSnicm {
98311827fbSnicm 	px = grid_view_x(gd, px);
99311827fbSnicm 	py = grid_view_y(gd, py);
100311827fbSnicm 
101ae4624e7Snicm 	grid_clear(gd, px, py, nx, ny, bg);
102311827fbSnicm }
103311827fbSnicm 
104311827fbSnicm /* Scroll region up. */
105311827fbSnicm void
grid_view_scroll_region_up(struct grid * gd,u_int rupper,u_int rlower,u_int bg)1066d5c64a0Snicm grid_view_scroll_region_up(struct grid *gd, u_int rupper, u_int rlower,
1076d5c64a0Snicm     u_int bg)
108311827fbSnicm {
109b3cd1016Snicm 	if (gd->flags & GRID_HISTORY) {
110bd28ed35Snicm 		grid_collect_history(gd);
111b3cd1016Snicm 		if (rupper == 0 && rlower == gd->sy - 1)
1126d5c64a0Snicm 			grid_scroll_history(gd, bg);
113b3cd1016Snicm 		else {
114311827fbSnicm 			rupper = grid_view_y(gd, rupper);
115311827fbSnicm 			rlower = grid_view_y(gd, rlower);
1166d5c64a0Snicm 			grid_scroll_history_region(gd, rupper, rlower, bg);
117b3cd1016Snicm 		}
118b3cd1016Snicm 	} else {
119b3cd1016Snicm 		rupper = grid_view_y(gd, rupper);
120b3cd1016Snicm 		rlower = grid_view_y(gd, rlower);
1216d5c64a0Snicm 		grid_move_lines(gd, rupper, rupper + 1, rlower - rupper, bg);
122311827fbSnicm 	}
123b3cd1016Snicm }
124311827fbSnicm 
125311827fbSnicm /* Scroll region down. */
126311827fbSnicm void
grid_view_scroll_region_down(struct grid * gd,u_int rupper,u_int rlower,u_int bg)1276d5c64a0Snicm grid_view_scroll_region_down(struct grid *gd, u_int rupper, u_int rlower,
1286d5c64a0Snicm     u_int bg)
129311827fbSnicm {
130311827fbSnicm 	rupper = grid_view_y(gd, rupper);
131311827fbSnicm 	rlower = grid_view_y(gd, rlower);
132311827fbSnicm 
1336d5c64a0Snicm 	grid_move_lines(gd, rupper + 1, rupper, rlower - rupper, bg);
134311827fbSnicm }
135311827fbSnicm 
136311827fbSnicm /* Insert lines. */
137311827fbSnicm void
grid_view_insert_lines(struct grid * gd,u_int py,u_int ny,u_int bg)138ae4624e7Snicm grid_view_insert_lines(struct grid *gd, u_int py, u_int ny, u_int bg)
139311827fbSnicm {
140311827fbSnicm 	u_int	sy;
141311827fbSnicm 
142311827fbSnicm 	py = grid_view_y(gd, py);
143311827fbSnicm 
144311827fbSnicm 	sy = grid_view_y(gd, gd->sy);
145311827fbSnicm 
146ae4624e7Snicm 	grid_move_lines(gd, py + ny, py, sy - py - ny, bg);
147311827fbSnicm }
148311827fbSnicm 
149311827fbSnicm /* Insert lines in region. */
150311827fbSnicm void
grid_view_insert_lines_region(struct grid * gd,u_int rlower,u_int py,u_int ny,u_int bg)151bfcd10e2Snicm grid_view_insert_lines_region(struct grid *gd, u_int rlower, u_int py,
152ae4624e7Snicm     u_int ny, u_int bg)
153311827fbSnicm {
154a6133b88Snicm 	u_int	ny2;
155a6133b88Snicm 
156311827fbSnicm 	rlower = grid_view_y(gd, rlower);
157311827fbSnicm 
158311827fbSnicm 	py = grid_view_y(gd, py);
159311827fbSnicm 
160a6133b88Snicm 	ny2 = rlower + 1 - py - ny;
161ae4624e7Snicm 	grid_move_lines(gd, rlower + 1 - ny2, py, ny2, bg);
162ae4624e7Snicm 	grid_clear(gd, 0, py + ny2, gd->sx, ny - ny2, bg);
163311827fbSnicm }
164311827fbSnicm 
165311827fbSnicm /* Delete lines. */
166311827fbSnicm void
grid_view_delete_lines(struct grid * gd,u_int py,u_int ny,u_int bg)167ae4624e7Snicm grid_view_delete_lines(struct grid *gd, u_int py, u_int ny, u_int bg)
168311827fbSnicm {
169311827fbSnicm 	u_int	sy;
170311827fbSnicm 
171311827fbSnicm 	py = grid_view_y(gd, py);
172311827fbSnicm 
173311827fbSnicm 	sy = grid_view_y(gd, gd->sy);
174311827fbSnicm 
175ae4624e7Snicm 	grid_move_lines(gd, py, py + ny, sy - py - ny, bg);
176ae4624e7Snicm 	grid_clear(gd, 0, sy - ny, gd->sx, py + ny - (sy - ny), bg);
177311827fbSnicm }
178311827fbSnicm 
179311827fbSnicm /* Delete lines inside scroll region. */
180311827fbSnicm void
grid_view_delete_lines_region(struct grid * gd,u_int rlower,u_int py,u_int ny,u_int bg)181bfcd10e2Snicm grid_view_delete_lines_region(struct grid *gd, u_int rlower, u_int py,
182ae4624e7Snicm     u_int ny, u_int bg)
183311827fbSnicm {
184a6133b88Snicm 	u_int	ny2;
185a6133b88Snicm 
186311827fbSnicm 	rlower = grid_view_y(gd, rlower);
187311827fbSnicm 
188311827fbSnicm 	py = grid_view_y(gd, py);
189311827fbSnicm 
190a6133b88Snicm 	ny2 = rlower + 1 - py - ny;
191ae4624e7Snicm 	grid_move_lines(gd, py, py + ny, ny2, bg);
192ae4624e7Snicm 	grid_clear(gd, 0, py + ny2, gd->sx, ny - ny2, bg);
193311827fbSnicm }
194311827fbSnicm 
195311827fbSnicm /* Insert characters. */
196311827fbSnicm void
grid_view_insert_cells(struct grid * gd,u_int px,u_int py,u_int nx,u_int bg)197ae4624e7Snicm grid_view_insert_cells(struct grid *gd, u_int px, u_int py, u_int nx, u_int bg)
198311827fbSnicm {
199311827fbSnicm 	u_int	sx;
200311827fbSnicm 
201311827fbSnicm 	px = grid_view_x(gd, px);
202311827fbSnicm 	py = grid_view_y(gd, py);
203311827fbSnicm 
204a876f247Snicm 	sx = grid_view_x(gd, gd->sx);
205311827fbSnicm 
2065de89178Snicm 	if (px >= sx - 1)
207ae4624e7Snicm 		grid_clear(gd, px, py, 1, 1, bg);
208311827fbSnicm 	else
209ae4624e7Snicm 		grid_move_cells(gd, px + nx, px, py, sx - px - nx, bg);
210311827fbSnicm }
211311827fbSnicm 
212311827fbSnicm /* Delete characters. */
213311827fbSnicm void
grid_view_delete_cells(struct grid * gd,u_int px,u_int py,u_int nx,u_int bg)214ae4624e7Snicm grid_view_delete_cells(struct grid *gd, u_int px, u_int py, u_int nx, u_int bg)
215311827fbSnicm {
216311827fbSnicm 	u_int	sx;
217311827fbSnicm 
218311827fbSnicm 	px = grid_view_x(gd, px);
219311827fbSnicm 	py = grid_view_y(gd, py);
220311827fbSnicm 
221cee98202Snicm 	sx = grid_view_x(gd, gd->sx);
222311827fbSnicm 
223ae4624e7Snicm 	grid_move_cells(gd, px, px + nx, py, sx - px - nx, bg);
2244e2e126aSnicm 	grid_clear(gd, sx - nx, py, px + nx - (sx - nx), 1, bg);
225311827fbSnicm }
226b6d61ae9Snicm 
227b6d61ae9Snicm /* Convert cells into a string. */
228b6d61ae9Snicm char *
grid_view_string_cells(struct grid * gd,u_int px,u_int py,u_int nx)229b6d61ae9Snicm grid_view_string_cells(struct grid *gd, u_int px, u_int py, u_int nx)
230b6d61ae9Snicm {
231b6d61ae9Snicm 	px = grid_view_x(gd, px);
232b6d61ae9Snicm 	py = grid_view_y(gd, py);
233b6d61ae9Snicm 
234*32b2c715Snicm 	return (grid_string_cells(gd, px, py, nx, NULL, 0, NULL));
235b6d61ae9Snicm }
236