mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-14 08:21:27 -04:00
scrolling: initial reverse scrolling support - no scroll regions
This commit is contained in:
parent
048f619b19
commit
a7a28ff581
4 changed files with 47 additions and 51 deletions
23
grid.c
23
grid.c
|
|
@ -8,12 +8,15 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
struct cell *
|
struct cell *
|
||||||
grid_get_range(struct grid *grid, size_t start, size_t *length)
|
grid_get_range(struct grid *grid, int start, int *length)
|
||||||
{
|
{
|
||||||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||||
assert(*length <= grid->size);
|
assert(*length <= grid->size);
|
||||||
|
|
||||||
size_t real_start = (grid->offset + start) % grid->size;
|
int real_start = (grid->offset + start) % grid->size;
|
||||||
|
if (real_start < 0)
|
||||||
|
real_start += grid->size;
|
||||||
|
assert(real_start >= 0);
|
||||||
assert(real_start < grid->size);
|
assert(real_start < grid->size);
|
||||||
|
|
||||||
*length = min(*length, grid->size - real_start);
|
*length = min(*length, grid->size - real_start);
|
||||||
|
|
@ -24,11 +27,11 @@ grid_get_range(struct grid *grid, size_t start, size_t *length)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
grid_memset(struct grid *grid, size_t start, int c, size_t length)
|
grid_memset(struct grid *grid, int start, int c, int length)
|
||||||
{
|
{
|
||||||
size_t left = length;
|
int left = length;
|
||||||
while (left > 0) {
|
while (left > 0) {
|
||||||
size_t count = left;
|
int count = left;
|
||||||
struct cell *cells = grid_get_range(grid, start, &count);
|
struct cell *cells = grid_get_range(grid, start, &count);
|
||||||
|
|
||||||
assert(count > 0);
|
assert(count > 0);
|
||||||
|
|
@ -42,14 +45,14 @@ grid_memset(struct grid *grid, size_t start, int c, size_t length)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
grid_memmove(struct grid *grid, size_t dst, size_t src, size_t length)
|
grid_memmove(struct grid *grid, int dst, int src, int length)
|
||||||
{
|
{
|
||||||
size_t left = length;
|
int left = length;
|
||||||
size_t copy_idx = 0;
|
int copy_idx = 0;
|
||||||
struct cell copy[left];
|
struct cell copy[left];
|
||||||
|
|
||||||
while (left > 0) {
|
while (left > 0) {
|
||||||
size_t count = left;
|
int count = left;
|
||||||
struct cell *src_cells = grid_get_range(grid, src, &count);
|
struct cell *src_cells = grid_get_range(grid, src, &count);
|
||||||
|
|
||||||
memcpy(©[copy_idx], src_cells, count * sizeof(copy[0]));
|
memcpy(©[copy_idx], src_cells, count * sizeof(copy[0]));
|
||||||
|
|
@ -63,7 +66,7 @@ grid_memmove(struct grid *grid, size_t dst, size_t src, size_t length)
|
||||||
copy_idx = 0;
|
copy_idx = 0;
|
||||||
|
|
||||||
while (left > 0) {
|
while (left > 0) {
|
||||||
size_t count = left;
|
int count = left;
|
||||||
struct cell *dst_cells = grid_get_range(grid, dst, &count);
|
struct cell *dst_cells = grid_get_range(grid, dst, &count);
|
||||||
|
|
||||||
memcpy(dst_cells, ©[copy_idx], count * sizeof(copy[0]));
|
memcpy(dst_cells, ©[copy_idx], count * sizeof(copy[0]));
|
||||||
|
|
|
||||||
6
grid.h
6
grid.h
|
|
@ -3,6 +3,6 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
|
|
||||||
struct cell *grid_get_range(struct grid *grid, size_t start, size_t *length);
|
struct cell *grid_get_range(struct grid *grid, int start, int *length);
|
||||||
void grid_memset(struct grid *grid, size_t start, int c, size_t length);
|
void grid_memset(struct grid *grid, int start, int c, int length);
|
||||||
void grid_memmove(struct grid *grid, size_t dst, size_t src, size_t length);
|
void grid_memmove(struct grid *grid, int dst, int src, int length);
|
||||||
|
|
|
||||||
19
main.c
19
main.c
|
|
@ -118,10 +118,19 @@ grid_render_update(struct context *c, struct buffer *buf, const struct damage *d
|
||||||
row += col == 0 ? 1 : 0)
|
row += col == 0 ? 1 : 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
//LOG_DBG("UPDATE: %d (%dx%d)", linear_cursor, row, col);
|
assert(row >= 0);
|
||||||
|
assert(row < c->term.rows);
|
||||||
|
assert(col >= 0);
|
||||||
|
assert(col < c->term.cols);
|
||||||
|
|
||||||
const struct cell *cell
|
int cell_idx = linear_cursor % c->term.grid->size;
|
||||||
= &c->term.grid->cells[linear_cursor % c->term.grid->size];
|
if (cell_idx < 0)
|
||||||
|
cell_idx += c->term.grid->size;
|
||||||
|
|
||||||
|
assert(cell_idx >= 0);
|
||||||
|
assert(cell_idx < c->term.rows * c->term.cols);
|
||||||
|
|
||||||
|
const struct cell *cell = &c->term.grid->cells[cell_idx];
|
||||||
|
|
||||||
/* Cursor here? */
|
/* Cursor here? */
|
||||||
bool has_cursor
|
bool has_cursor
|
||||||
|
|
@ -376,7 +385,7 @@ grid_render_scroll_reverse(struct context *c, struct buffer *buf,
|
||||||
struct damage erase = {
|
struct damage erase = {
|
||||||
.type = DAMAGE_ERASE,
|
.type = DAMAGE_ERASE,
|
||||||
.range = {
|
.range = {
|
||||||
.start = dmg->scroll.region.start * cols,
|
.start = c->term.grid->offset + dmg->scroll.region.start * cols,
|
||||||
.length = min(dmg->scroll.region.end - dmg->scroll.region.start,
|
.length = min(dmg->scroll.region.end - dmg->scroll.region.start,
|
||||||
dmg->scroll.lines) * cols,
|
dmg->scroll.lines) * cols,
|
||||||
},
|
},
|
||||||
|
|
@ -461,6 +470,8 @@ grid_render(struct context *c)
|
||||||
last_cursor = c->term.grid->offset + c->term.cursor.linear;
|
last_cursor = c->term.grid->offset + c->term.cursor.linear;
|
||||||
|
|
||||||
c->term.grid->offset %= c->term.grid->size;
|
c->term.grid->offset %= c->term.grid->size;
|
||||||
|
if (c->term.grid->offset < 0)
|
||||||
|
c->term.grid->offset += c->term.grid->size;
|
||||||
|
|
||||||
//cairo_surface_flush(buf->cairo_surface);
|
//cairo_surface_flush(buf->cairo_surface);
|
||||||
wl_surface_attach(c->wl.surface, buf->wl_buf, 0, 0);
|
wl_surface_attach(c->wl.surface, buf->wl_buf, 0, 0);
|
||||||
|
|
|
||||||
50
terminal.c
50
terminal.c
|
|
@ -134,8 +134,7 @@ term_damage_scroll(struct terminal *term, enum damage_type damage_type,
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
assert(false);
|
|
||||||
|
|
||||||
if (tll_length(term->grid->scroll_damage) > 0) {
|
if (tll_length(term->grid->scroll_damage) > 0) {
|
||||||
struct damage *dmg = &tll_back(term->grid->scroll_damage);
|
struct damage *dmg = &tll_back(term->grid->scroll_damage);
|
||||||
|
|
@ -187,11 +186,11 @@ term_cursor_to(struct terminal *term, int row, int col)
|
||||||
term->cursor.col = col;
|
term->cursor.col = col;
|
||||||
term->cursor.row = row;
|
term->cursor.row = row;
|
||||||
|
|
||||||
size_t len = term->cols;
|
int len = term->cols;
|
||||||
term->grid->cur_line = grid_get_range(
|
term->grid->cur_line = grid_get_range(
|
||||||
term->grid, term->cursor.linear - col, &len);
|
term->grid, term->cursor.linear - col, &len);
|
||||||
|
|
||||||
assert(len == (size_t)term->cols);
|
assert(len == term->cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -277,11 +276,11 @@ term_scroll_partial(struct terminal *term, struct scroll_region region, int rows
|
||||||
|
|
||||||
term_damage_scroll(term, DAMAGE_SCROLL, region, rows);
|
term_damage_scroll(term, DAMAGE_SCROLL, region, rows);
|
||||||
|
|
||||||
size_t len = term->cols;
|
int len = term->cols;
|
||||||
term->grid->cur_line = grid_get_range(
|
term->grid->cur_line = grid_get_range(
|
||||||
term->grid, term->cursor.linear - term->cursor.col, &len);
|
term->grid, term->cursor.linear - term->cursor.col, &len);
|
||||||
|
|
||||||
assert(len == (size_t)term->cols);
|
assert(len == term->cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -294,37 +293,20 @@ void
|
||||||
term_scroll_reverse_partial(struct terminal *term,
|
term_scroll_reverse_partial(struct terminal *term,
|
||||||
struct scroll_region region, int rows)
|
struct scroll_region region, int rows)
|
||||||
{
|
{
|
||||||
if (rows >= region.end - region.start) {
|
assert(region.start == 0);
|
||||||
assert(false && "todo");
|
assert(region.end == term->rows);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
int cell_dst = (region.start + rows) * term->cols;
|
|
||||||
int cell_src = (region.start + 0) * term->cols;
|
|
||||||
int cell_count = (region.end - region.start - rows) * term->cols;
|
|
||||||
|
|
||||||
LOG_DBG("moving %d lines from row %d to row %d", cell_count / term->cols,
|
|
||||||
cell_src / term->cols, cell_dst / term->cols);
|
|
||||||
|
|
||||||
const int bytes = cell_count * sizeof(term->grid->cells[0]);
|
|
||||||
memmove(
|
|
||||||
&term->grid->cells[cell_dst], &term->grid->cells[cell_src],
|
|
||||||
bytes);
|
|
||||||
|
|
||||||
memset(&term->grid->cells[cell_src], 0,
|
|
||||||
rows * term->cols * sizeof(term->grid->cells[0]));
|
|
||||||
|
|
||||||
term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows);
|
|
||||||
#else
|
|
||||||
/* TODO */
|
|
||||||
assert(false);
|
|
||||||
assert(region.start == 0 && region.end == 0);
|
|
||||||
assert(rows < term->rows);
|
|
||||||
|
|
||||||
term->grid->offset -= rows * term->cols;
|
term->grid->offset -= rows * term->cols;
|
||||||
|
|
||||||
|
grid_memset(term->grid, region.start * term->cols, 0, rows * term->cols);
|
||||||
|
|
||||||
term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows);
|
term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows);
|
||||||
#endif
|
|
||||||
|
int len = term->cols;
|
||||||
|
term->grid->cur_line = grid_get_range(
|
||||||
|
term->grid, term->cursor.linear - term->cursor.col, &len);
|
||||||
|
|
||||||
|
assert(len == term->cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue