aboutsummaryrefslogtreecommitdiff
path: root/grid.c
diff options
context:
space:
mode:
authorThomas Adam <thomas@xteddy.org>2016-10-13 22:01:12 +0100
committerThomas Adam <thomas@xteddy.org>2016-10-13 22:01:12 +0100
commitad5a561adbfb8241633e40ca9ff9d270522f96d8 (patch)
tree2287a582551cda974ec926fd35ed90a31a7af2b2 /grid.c
parentf691d46a16b52b93a64425ff3471eb2675125b57 (diff)
parent4179b4242411f41a22d9743b4eff3b19ef69b3e8 (diff)
downloadrtmux-ad5a561adbfb8241633e40ca9ff9d270522f96d8.tar.gz
rtmux-ad5a561adbfb8241633e40ca9ff9d270522f96d8.tar.bz2
rtmux-ad5a561adbfb8241633e40ca9ff9d270522f96d8.zip
Merge branch 'obsd-master'
Diffstat (limited to 'grid.c')
-rw-r--r--grid.c106
1 files changed, 60 insertions, 46 deletions
diff --git a/grid.c b/grid.c
index 35de2aef..d0a28463 100644
--- a/grid.c
+++ b/grid.c
@@ -43,7 +43,8 @@ const struct grid_cell_entry grid_default_entry = {
0, { .data = { 0, 8, 8, ' ' } }
};
-static void grid_expand_line(struct grid *, u_int, u_int);
+static void grid_expand_line(struct grid *, u_int, u_int, u_int);
+static void grid_empty_line(struct grid *, u_int, u_int);
static void grid_reflow_copy(struct grid_line *, u_int, struct grid_line *,
u_int, u_int);
@@ -60,9 +61,10 @@ static void grid_string_cells_code(const struct grid_cell *,
/* Copy default into a cell. */
static void
-grid_clear_cell(struct grid *gd, u_int px, u_int py)
+grid_clear_cell(struct grid *gd, u_int px, u_int py, u_int bg)
{
gd->linedata[py].celldata[px] = grid_default_entry;
+ gd->linedata[py].celldata[px].data.bg = bg;
}
/* Check grid y position. */
@@ -162,7 +164,7 @@ grid_compare(struct grid *ga, struct grid *gb)
* and shift up.
*/
void
-grid_collect_history(struct grid *gd)
+grid_collect_history(struct grid *gd, u_int bg)
{
u_int yy;
@@ -173,7 +175,7 @@ grid_collect_history(struct grid *gd)
if (yy < 1)
yy = 1;
- grid_move_lines(gd, 0, yy, gd->hsize + gd->sy - yy);
+ grid_move_lines(gd, 0, yy, gd->hsize + gd->sy - yy, bg);
gd->hsize -= yy;
if (gd->hscrolled > gd->hsize)
gd->hscrolled = gd->hsize;
@@ -184,14 +186,14 @@ grid_collect_history(struct grid *gd)
* allocate a new line at the bottom and move the history size indicator.
*/
void
-grid_scroll_history(struct grid *gd)
+grid_scroll_history(struct grid *gd, u_int bg)
{
u_int yy;
yy = gd->hsize + gd->sy;
gd->linedata = xreallocarray(gd->linedata, yy + 1,
sizeof *gd->linedata);
- memset(&gd->linedata[yy], 0, sizeof gd->linedata[yy]);
+ grid_empty_line(gd, yy, bg);
gd->hscrolled++;
gd->hsize++;
@@ -201,8 +203,8 @@ grid_scroll_history(struct grid *gd)
void
grid_clear_history(struct grid *gd)
{
- grid_clear_lines(gd, 0, gd->hsize);
- grid_move_lines(gd, 0, gd->hsize, gd->sy);
+ grid_clear_lines(gd, 0, gd->hsize, 8);
+ grid_move_lines(gd, 0, gd->hsize, gd->sy, 8);
gd->hscrolled = 0;
gd->hsize = 0;
@@ -247,7 +249,7 @@ grid_scroll_history_region(struct grid *gd, u_int upper, u_int lower)
/* Expand line to fit to cell. */
static void
-grid_expand_line(struct grid *gd, u_int py, u_int sx)
+grid_expand_line(struct grid *gd, u_int py, u_int sx, u_int bg)
{
struct grid_line *gl;
u_int xx;
@@ -258,10 +260,19 @@ grid_expand_line(struct grid *gd, u_int py, u_int sx)
gl->celldata = xreallocarray(gl->celldata, sx, sizeof *gl->celldata);
for (xx = gl->cellsize; xx < sx; xx++)
- grid_clear_cell(gd, xx, py);
+ grid_clear_cell(gd, xx, py, bg);
gl->cellsize = sx;
}
+/* Empty a line and set background colour if needed. */
+static void
+grid_empty_line(struct grid *gd, u_int py, u_int bg)
+{
+ memset(&gd->linedata[py], 0, sizeof gd->linedata[py]);
+ if (bg != 8)
+ grid_expand_line(gd, py, gd->sx, bg);
+}
+
/* Peek at grid line. */
const struct grid_line *
grid_peek_line(struct grid *gd, u_int py)
@@ -317,11 +328,14 @@ grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc)
if (grid_check_y(gd, py) != 0)
return;
- grid_expand_line(gd, py, px + 1);
+ grid_expand_line(gd, py, px + 1, 8);
gl = &gd->linedata[py];
gce = &gl->celldata[px];
+ if (px + 1 > gl->cellused)
+ gl->cellused = px + 1;
+
extended = (gce->flags & GRID_FLAG_EXTENDED);
if (!extended && (gc->data.size != 1 || gc->data.width != 1))
extended = 1;
@@ -358,7 +372,7 @@ grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc)
/* Clear area. */
void
-grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny)
+grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny, u_int bg)
{
u_int xx, yy;
@@ -366,7 +380,7 @@ grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny)
return;
if (px == 0 && nx == gd->sx) {
- grid_clear_lines(gd, py, ny);
+ grid_clear_lines(gd, py, ny, bg);
return;
}
@@ -376,23 +390,23 @@ grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny)
return;
for (yy = py; yy < py + ny; yy++) {
- if (px >= gd->linedata[yy].cellsize)
+ if (px + nx >= gd->sx && px < gd->linedata[yy].cellused)
+ gd->linedata[yy].cellused = px;
+ if (px > gd->linedata[yy].cellsize && bg == 8)
continue;
- if (px + nx >= gd->linedata[yy].cellsize) {
+ if (px + nx >= gd->linedata[yy].cellsize && bg == 8) {
gd->linedata[yy].cellsize = px;
continue;
}
- for (xx = px; xx < px + nx; xx++) {
- if (xx >= gd->linedata[yy].cellsize)
- break;
- grid_clear_cell(gd, xx, yy);
- }
+ grid_expand_line(gd, yy, px + nx, bg);
+ for (xx = px; xx < px + nx; xx++)
+ grid_clear_cell(gd, xx, yy, bg);
}
}
/* Clear lines. This just frees and truncates the lines. */
void
-grid_clear_lines(struct grid *gd, u_int py, u_int ny)
+grid_clear_lines(struct grid *gd, u_int py, u_int ny, u_int bg)
{
struct grid_line *gl;
u_int yy;
@@ -409,13 +423,13 @@ grid_clear_lines(struct grid *gd, u_int py, u_int ny)
gl = &gd->linedata[yy];
free(gl->celldata);
free(gl->extddata);
- memset(gl, 0, sizeof *gl);
+ grid_empty_line(gd, yy, bg);
}
}
/* Move a group of lines. */
void
-grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny)
+grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny, u_int bg)
{
u_int yy;
@@ -435,7 +449,7 @@ grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny)
for (yy = dy; yy < dy + ny; yy++) {
if (yy >= py && yy < py + ny)
continue;
- grid_clear_lines(gd, yy, 1);
+ grid_clear_lines(gd, yy, 1, bg);
}
memmove(&gd->linedata[dy], &gd->linedata[py],
@@ -443,15 +457,15 @@ grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny)
/* Wipe any lines that have been moved (without freeing them). */
for (yy = py; yy < py + ny; yy++) {
- if (yy >= dy && yy < dy + ny)
- continue;
- memset(&gd->linedata[yy], 0, sizeof gd->linedata[yy]);
+ if (yy < dy || yy >= dy + ny)
+ grid_empty_line(gd, yy, bg);
}
}
/* Move a group of cells. */
void
-grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx)
+grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx,
+ u_int bg)
{
struct grid_line *gl;
u_int xx;
@@ -463,8 +477,8 @@ grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx)
return;
gl = &gd->linedata[py];
- grid_expand_line(gd, py, px + nx);
- grid_expand_line(gd, py, dx + nx);
+ grid_expand_line(gd, py, px + nx, 8);
+ grid_expand_line(gd, py, dx + nx, 8);
memmove(&gl->celldata[dx], &gl->celldata[px],
nx * sizeof *gl->celldata);
@@ -472,7 +486,7 @@ grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx)
for (xx = px; xx < px + nx; xx++) {
if (xx >= dx && xx < dx + nx)
continue;
- grid_clear_cell(gd, xx, py);
+ grid_clear_cell(gd, xx, py, bg);
}
}
@@ -748,7 +762,7 @@ grid_duplicate_lines(struct grid *dst, u_int dy, struct grid *src, u_int sy,
ny = dst->hsize + dst->sy - dy;
if (sy + ny > src->hsize + src->sy)
ny = src->hsize + src->sy - sy;
- grid_clear_lines(dst, dy, ny);
+ grid_clear_lines(dst, dy, ny, 8);
for (yy = 0; yy < ny; yy++) {
srcl = &src->linedata[sy];
@@ -810,28 +824,28 @@ grid_reflow_join(struct grid *dst, u_int *py, struct grid_line *src_gl,
u_int left, to_copy, ox, nx;
/* How much is left on the old line? */
- left = new_x - dst_gl->cellsize;
+ left = new_x - dst_gl->cellused;
/* Work out how much to append. */
- to_copy = src_gl->cellsize;
+ to_copy = src_gl->cellused;
if (to_copy > left)
to_copy = left;
- ox = dst_gl->cellsize;
+ ox = dst_gl->cellused;
nx = ox + to_copy;
/* Resize the destination line. */
dst_gl->celldata = xreallocarray(dst_gl->celldata, nx,
sizeof *dst_gl->celldata);
- dst_gl->cellsize = nx;
+ dst_gl->cellsize = dst_gl->cellused = nx;
/* Append as much as possible. */
grid_reflow_copy(dst_gl, ox, src_gl, 0, to_copy);
/* If there is any left in the source, split it. */
- if (src_gl->cellsize > to_copy) {
+ if (src_gl->cellused > to_copy) {
dst_gl->flags |= GRID_LINE_WRAPPED;
- src_gl->cellsize -= to_copy;
+ src_gl->cellused -= to_copy;
grid_reflow_split(dst, py, src_gl, new_x, to_copy);
}
}
@@ -845,22 +859,22 @@ grid_reflow_split(struct grid *dst, u_int *py, struct grid_line *src_gl,
u_int to_copy;
/* Loop and copy sections of the source line. */
- while (src_gl->cellsize > 0) {
+ while (src_gl->cellused > 0) {
/* Create new line. */
if (*py >= dst->hsize + dst->sy)
- grid_scroll_history(dst);
+ grid_scroll_history(dst, 8);
dst_gl = &dst->linedata[*py];
(*py)++;
/* How much should we copy? */
to_copy = new_x;
- if (to_copy > src_gl->cellsize)
- to_copy = src_gl->cellsize;
+ if (to_copy > src_gl->cellused)
+ to_copy = src_gl->cellused;
/* Expand destination line. */
dst_gl->celldata = xreallocarray(NULL, to_copy,
sizeof *dst_gl->celldata);
- dst_gl->cellsize = to_copy;
+ dst_gl->cellsize = dst_gl->cellused = to_copy;
dst_gl->flags |= GRID_LINE_WRAPPED;
/* Copy the data. */
@@ -868,7 +882,7 @@ grid_reflow_split(struct grid *dst, u_int *py, struct grid_line *src_gl,
/* Move offset and reduce old line size. */
offset += to_copy;
- src_gl->cellsize -= to_copy;
+ src_gl->cellused -= to_copy;
}
/* Last line is not wrapped. */
@@ -884,7 +898,7 @@ grid_reflow_move(struct grid *dst, u_int *py, struct grid_line *src_gl)
/* Create new line. */
if (*py >= dst->hsize + dst->sy)
- grid_scroll_history(dst);
+ grid_scroll_history(dst, 8);
dst_gl = &dst->linedata[*py];
(*py)++;
@@ -916,7 +930,7 @@ grid_reflow(struct grid *dst, struct grid *src, u_int new_x)
src_gl = src->linedata + line;
if (!previous_wrapped) {
/* Wasn't wrapped. If smaller, move to destination. */
- if (src_gl->cellsize <= new_x)
+ if (src_gl->cellused <= new_x)
grid_reflow_move(dst, &py, src_gl);
else
grid_reflow_split(dst, &py, src_gl, new_x, 0);