summaryrefslogtreecommitdiff
path: root/src/screen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/screen.c')
-rw-r--r--src/screen.c128
1 files changed, 34 insertions, 94 deletions
diff --git a/src/screen.c b/src/screen.c
index d9dfe31..bd65564 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -560,6 +560,21 @@ void term_screen_erase(struct term *t, int mode)
}
}
+/* Reset a recycled row's contents and identity; callers choose its version. */
+static inline void reset_scrolled_row(struct term *t, struct srow *row, bool def)
+{
+ row->kind = ROW_CELLS;
+ row->uid = ++t->next_row_uid;
+ if (def) {
+ row->len = 0;
+ row->flags = 0;
+ } else {
+ fill_cells(row->cells, t->cols, t->cur_fg, t->cur_bg);
+ row->len = (uint16_t)t->cols;
+ row->flags = RF_TAIL_PADDED;
+ }
+}
+
static void rotate_and_clear_srows(struct term *t, struct srow *base, int height,
int count, bool down, bool def)
{
@@ -568,50 +583,18 @@ static void rotate_and_clear_srows(struct term *t, struct srow *base, int height
if (!saved)
return;
- if (!down) {
- memcpy(saved, base, (size_t)count * sizeof(struct srow));
- memmove(base, base + count, (size_t)(height - count) * sizeof(struct srow));
- memcpy(base + height - count, saved, (size_t)count * sizeof(struct srow));
-
- for (int i = 0; i < height - count; i++)
- base[i].version++;
-
- for (int i = 0; i < count; i++) {
- struct srow *dst = &base[height - count + i];
- dst->kind = ROW_CELLS;
- dst->uid = ++t->next_row_uid;
- dst->version = 1;
- if (def) {
- dst->len = 0;
- dst->flags = 0;
- } else {
- fill_cells(dst->cells, t->cols, t->cur_fg, t->cur_bg);
- dst->len = (uint16_t)t->cols;
- dst->flags = RF_TAIL_PADDED;
- }
- }
- } else {
- memcpy(saved, base + height - count, (size_t)count * sizeof(struct srow));
- memmove(base + count, base, (size_t)(height - count) * sizeof(struct srow));
- memcpy(base, saved, (size_t)count * sizeof(struct srow));
-
- for (int i = 0; i < height - count; i++)
- base[count + i].version++;
-
- for (int i = 0; i < count; i++) {
- struct srow *dst = &base[i];
- dst->kind = ROW_CELLS;
- dst->uid = ++t->next_row_uid;
- dst->version = 1;
- if (def) {
- dst->len = 0;
- dst->flags = 0;
- } else {
- fill_cells(dst->cells, t->cols, t->cur_fg, t->cur_bg);
- dst->len = (uint16_t)t->cols;
- dst->flags = RF_TAIL_PADDED;
- }
- }
+ int kept = down ? count : 0;
+ int cleared = down ? 0 : height - count;
+ memcpy(saved, base + (down ? height - count : 0), (size_t)count * sizeof(struct srow));
+ memmove(base + kept, base + (down ? 0 : count),
+ (size_t)(height - count) * sizeof(struct srow));
+ memcpy(base + cleared, saved, (size_t)count * sizeof(struct srow));
+ for (int i = 0; i < height - count; i++)
+ base[kept + i].version++;
+ for (int i = 0; i < count; i++) {
+ struct srow *dst = &base[cleared + i];
+ reset_scrolled_row(t, dst, def);
+ dst->version = 1;
}
if (saved != tmp)
free(saved);
@@ -659,17 +642,8 @@ void term_screen_scroll_region(struct term *t, int top, int bottom, int count,
if (history) {
screen_new_row(t, row);
} else {
- row->kind = ROW_CELLS;
- row->uid = ++t->next_row_uid;
+ reset_scrolled_row(t, row, def);
row->version++;
- if (def) {
- row->len = 0;
- row->flags = 0;
- } else {
- fill_cells(row->cells, t->cols, t->cur_fg, t->cur_bg);
- row->len = (uint16_t)t->cols;
- row->flags = RF_TAIL_PADDED;
- }
}
}
int new_top = orig_top + count;
@@ -696,17 +670,8 @@ void term_screen_scroll_region(struct term *t, int top, int bottom, int count,
int p = orig_top + (rows - count) + i;
if (p >= rows) p -= rows;
struct srow *row = &s->slot[p];
- row->kind = ROW_CELLS;
- row->uid = ++t->next_row_uid;
+ reset_scrolled_row(t, row, def);
row->version = 1;
- if (def) {
- row->len = 0;
- row->flags = 0;
- } else {
- fill_cells(row->cells, t->cols, t->cur_fg, t->cur_bg);
- row->len = (uint16_t)t->cols;
- row->flags = RF_TAIL_PADDED;
- }
}
int new_top = orig_top - count;
if (new_top < 0) new_top += rows;
@@ -730,36 +695,11 @@ void term_screen_scroll_region(struct term *t, int top, int bottom, int count,
if (count == height) {
int start = phys_row(t, top);
- if (start + height <= s->rows) {
- for (int i = 0; i < height; i++) {
- struct srow *dst = &s->slot[start + i];
- dst->kind = ROW_CELLS;
- dst->uid = ++t->next_row_uid;
- dst->version++;
- if (def) {
- dst->len = 0;
- dst->flags = 0;
- } else {
- fill_cells(dst->cells, t->cols, t->cur_fg, t->cur_bg);
- dst->len = (uint16_t)t->cols;
- dst->flags = RF_TAIL_PADDED;
- }
- }
- } else {
- for (int y = top; y <= bottom; y++) {
- struct srow *dst = screen_get_row(s, y);
- dst->kind = ROW_CELLS;
- dst->uid = ++t->next_row_uid;
- dst->version++;
- if (def) {
- dst->len = 0;
- dst->flags = 0;
- } else {
- fill_cells(dst->cells, t->cols, t->cur_fg, t->cur_bg);
- dst->len = (uint16_t)t->cols;
- dst->flags = RF_TAIL_PADDED;
- }
- }
+ for (int i = 0; i < height; i++) {
+ int p = start + i;
+ struct srow *dst = &s->slot[p >= s->rows ? p - s->rows : p];
+ reset_scrolled_row(t, dst, def);
+ dst->version++;
}
} else {
int start = phys_row(t, top);