2019-07-09 16:26:36 +02:00
|
|
|
#include "commands.h"
|
|
|
|
|
|
|
|
|
|
#define LOG_MODULE "commands"
|
|
|
|
|
#define LOG_ENABLE_DBG 1
|
|
|
|
|
#include "log.h"
|
|
|
|
|
#include "terminal.h"
|
|
|
|
|
#include "render.h"
|
|
|
|
|
#include "grid.h"
|
|
|
|
|
|
|
|
|
|
#define max(x, y) ((x) > (y) ? (x) : (y))
|
2019-07-10 09:29:36 +02:00
|
|
|
#define min(x, y) ((x) < (y) ? (x) : (y))
|
2019-07-09 16:26:36 +02:00
|
|
|
|
|
|
|
|
void
|
2019-07-10 09:15:37 +02:00
|
|
|
cmd_scrollback_up(struct terminal *term, int rows)
|
2019-07-09 16:26:36 +02:00
|
|
|
{
|
2019-07-10 09:15:37 +02:00
|
|
|
if (term->grid == &term->alt)
|
|
|
|
|
return;
|
|
|
|
|
|
2019-07-10 09:29:36 +02:00
|
|
|
rows = min(rows, term->grid->num_rows - term->rows);
|
|
|
|
|
|
2019-07-09 16:26:36 +02:00
|
|
|
assert(term->grid->offset >= 0);
|
2019-07-10 09:29:36 +02:00
|
|
|
assert(rows <= term->rows);
|
2019-07-09 16:26:36 +02:00
|
|
|
|
2019-07-10 09:29:36 +02:00
|
|
|
int new_view = (term->grid->view + term->grid->num_rows - rows) % term->grid->num_rows;
|
2019-07-09 16:26:36 +02:00
|
|
|
assert(new_view >= 0);
|
|
|
|
|
assert(new_view < term->grid->num_rows);
|
|
|
|
|
|
2019-07-10 09:15:37 +02:00
|
|
|
/* Avoid scrolling in uninitialized rows */
|
2019-07-09 16:26:36 +02:00
|
|
|
while (!term->grid->rows[new_view]->initialized)
|
|
|
|
|
new_view = (new_view + 1) % term->grid->num_rows;
|
|
|
|
|
|
2019-07-10 09:29:36 +02:00
|
|
|
/* Don't scroll past scrollback history */
|
2019-07-10 09:55:53 +02:00
|
|
|
int end = (term->grid->offset + term->rows - 1) % term->grid->num_rows;
|
2019-07-10 09:29:36 +02:00
|
|
|
if (end >= term->grid->offset) {
|
|
|
|
|
/* Not wrapped */
|
2019-07-10 09:55:53 +02:00
|
|
|
if (new_view >= term->grid->offset && new_view <= end)
|
2019-07-10 09:29:36 +02:00
|
|
|
new_view = end;
|
|
|
|
|
} else {
|
2019-07-10 09:55:53 +02:00
|
|
|
if (new_view >= term->grid->offset || new_view <= end)
|
2019-07-10 09:29:36 +02:00
|
|
|
new_view = end;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-09 16:26:36 +02:00
|
|
|
LOG_DBG("scrollback UP: %d -> %d (offset = %d, rows = %d)",
|
|
|
|
|
term->grid->view, new_view, term->grid->offset, term->grid->num_rows);
|
2019-07-10 09:30:35 +02:00
|
|
|
|
|
|
|
|
if (new_view == term->grid->view)
|
|
|
|
|
return;
|
|
|
|
|
|
2019-07-09 16:26:36 +02:00
|
|
|
term->grid->view = new_view;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < term->rows; i++)
|
|
|
|
|
grid_row_in_view(term->grid, i)->dirty = true;
|
|
|
|
|
|
|
|
|
|
if (term->frame_callback == NULL)
|
|
|
|
|
grid_render(term);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2019-07-10 09:15:37 +02:00
|
|
|
cmd_scrollback_down(struct terminal *term, int rows)
|
2019-07-09 16:26:36 +02:00
|
|
|
{
|
2019-07-10 09:15:37 +02:00
|
|
|
if (term->grid == &term->alt)
|
|
|
|
|
return;
|
|
|
|
|
|
2019-07-10 09:29:36 +02:00
|
|
|
rows = min(rows, term->grid->num_rows - term->rows);
|
|
|
|
|
|
2019-07-09 16:26:36 +02:00
|
|
|
assert(term->grid->offset >= 0);
|
|
|
|
|
|
2019-07-10 09:29:36 +02:00
|
|
|
int new_view = (term->grid->view + rows) % term->grid->num_rows;
|
2019-07-09 16:26:36 +02:00
|
|
|
assert(new_view >= 0);
|
|
|
|
|
assert(new_view < term->grid->num_rows);
|
|
|
|
|
|
2019-07-10 09:15:37 +02:00
|
|
|
/* Prevent scrolling in uninitialized rows */
|
|
|
|
|
bool all_initialized = false;
|
|
|
|
|
do {
|
|
|
|
|
all_initialized = true;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < term->rows; i++) {
|
|
|
|
|
int row_no = (new_view + i) % term->grid->num_rows;
|
|
|
|
|
if (!term->grid->rows[row_no]->initialized) {
|
|
|
|
|
all_initialized = false;
|
|
|
|
|
new_view--;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} while (!all_initialized);
|
2019-07-09 16:26:36 +02:00
|
|
|
|
2019-07-10 09:29:36 +02:00
|
|
|
/* Don't scroll past scrollback history */
|
2019-07-10 09:55:53 +02:00
|
|
|
int end = (term->grid->offset + term->rows - 1) % term->grid->num_rows;
|
2019-07-10 09:29:36 +02:00
|
|
|
if (end >= term->grid->offset) {
|
|
|
|
|
/* Not wrapped */
|
2019-07-10 09:55:53 +02:00
|
|
|
if (new_view >= term->grid->offset && new_view <= end)
|
2019-07-10 09:29:36 +02:00
|
|
|
new_view = term->grid->offset;
|
|
|
|
|
} else {
|
2019-07-10 09:55:53 +02:00
|
|
|
if (new_view >= term->grid->offset || new_view <= end)
|
2019-07-10 09:29:36 +02:00
|
|
|
new_view = term->grid->offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-07-09 16:26:36 +02:00
|
|
|
LOG_DBG("scrollback DOWN: %d -> %d (offset = %d, rows = %d)",
|
|
|
|
|
term->grid->view, new_view, term->grid->offset, term->grid->num_rows);
|
2019-07-10 09:30:35 +02:00
|
|
|
|
|
|
|
|
if (new_view == term->grid->view)
|
|
|
|
|
return;
|
|
|
|
|
|
2019-07-09 16:26:36 +02:00
|
|
|
term->grid->view = new_view;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < term->rows; i++)
|
|
|
|
|
grid_row_in_view(term->grid, i)->dirty = true;
|
|
|
|
|
|
|
|
|
|
if (term->frame_callback == NULL)
|
|
|
|
|
grid_render(term);
|
|
|
|
|
}
|