summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2016-05-04 02:30:51 -0400
committerJesse Luehrs <doy@tozt.net>2016-05-04 04:30:58 -0400
commit52f3852bd38c9c9bbf1e4eb1ffbcb8eecee1fd58 (patch)
tree24af335563f458095cbc3de8bb6a80c2cd6cd4b3
parent90422fb932153b0fa414480be0ffb1ec641b83da (diff)
downloadlibvt100-52f3852bd38c9c9bbf1e4eb1ffbcb8eecee1fd58.tar.gz
libvt100-52f3852bd38c9c9bbf1e4eb1ffbcb8eecee1fd58.zip
handle moving and scrolling separately
only lf/ri should be scrolling, and only if they start on the border of the scroll region and try to move off of it. also, all absolute movement should be absolute in the context of the full terminal, but relative vertical movement should be clamped to the scroll regions.
-rw-r--r--src/parser.c40
-rw-r--r--src/parser.l40
-rw-r--r--src/screen.c58
-rw-r--r--src/screen.h4
4 files changed, 80 insertions, 62 deletions
diff --git a/src/parser.c b/src/parser.c
index bff3be1..cef8907 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -2474,7 +2474,7 @@ static void vt100_parser_handle_bel(VT100Screen *vt)
static void vt100_parser_handle_bs(VT100Screen *vt)
{
DEBUG_TRACE1("BS");
- vt100_screen_move_to(vt, vt->grid->cur.row, vt->grid->cur.col - 1, 0);
+ vt100_screen_move_to(vt, vt->grid->cur.row, vt->grid->cur.col - 1);
}
static void vt100_parser_handle_tab(VT100Screen *vt)
@@ -2482,19 +2482,19 @@ static void vt100_parser_handle_tab(VT100Screen *vt)
DEBUG_TRACE1("TAB");
vt100_screen_move_to(
vt, vt->grid->cur.row,
- vt->grid->cur.col - (vt->grid->cur.col % 8) + 8, 0);
+ vt->grid->cur.col - (vt->grid->cur.col % 8) + 8);
}
static void vt100_parser_handle_lf(VT100Screen *vt)
{
DEBUG_TRACE1("LF");
- vt100_screen_move_to(vt, vt->grid->cur.row + 1, vt->grid->cur.col, 1);
+ vt100_screen_move_down_or_scroll(vt);
}
static void vt100_parser_handle_cr(VT100Screen *vt)
{
DEBUG_TRACE1("CR");
- vt100_screen_move_to(vt, vt->grid->cur.row, 0, 0);
+ vt100_screen_move_to(vt, vt->grid->cur.row, 0);
}
static void vt100_parser_handle_deckpam(VT100Screen *vt)
@@ -2512,7 +2512,7 @@ static void vt100_parser_handle_deckpnm(VT100Screen *vt)
static void vt100_parser_handle_ri(VT100Screen *vt)
{
DEBUG_TRACE1("RI");
- vt100_screen_move_to(vt, vt->grid->cur.row - 1, vt->grid->cur.col, 1);
+ vt100_screen_move_up_or_scroll(vt);
}
static void vt100_parser_handle_ris(VT100Screen *vt)
@@ -2521,7 +2521,7 @@ static void vt100_parser_handle_ris(VT100Screen *vt)
vt100_screen_use_normal_buffer(vt);
vt100_screen_set_scroll_region(
vt, 0, vt->grid->max.row - 1, 0, vt->grid->max.col - 1);
- vt100_screen_move_to(vt, 0, 0, 0);
+ vt100_screen_move_to(vt, 0, 0);
vt100_screen_clear_screen(vt);
vt100_screen_save_cursor(vt);
vt100_screen_reset_text_attributes(vt);
@@ -2610,21 +2610,29 @@ static void vt100_parser_handle_ich(VT100Screen *vt, char *buf, size_t len)
static void vt100_parser_handle_cuu(VT100Screen *vt, char *buf, size_t len)
{
int params[VT100_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams;
+ int row = vt->grid->cur.row, new_row;
DEBUG_TRACE3("CUU", buf + 2, len - 3);
vt100_parser_extract_csi_params(buf + 2, len - 3, params, &nparams);
- vt100_screen_move_to(
- vt, vt->grid->cur.row - params[0], vt->grid->cur.col, 0);
+ new_row = row - params[0];
+ if (row >= vt->grid->scroll_top && new_row < vt->grid->scroll_top) {
+ new_row = vt->grid->scroll_top;
+ }
+ vt100_screen_move_to(vt, new_row, vt->grid->cur.col);
}
static void vt100_parser_handle_cud(VT100Screen *vt, char *buf, size_t len)
{
int params[VT100_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams;
+ int row = vt->grid->cur.row, new_row;
DEBUG_TRACE3("CUD", buf + 2, len - 3);
vt100_parser_extract_csi_params(buf + 2, len - 3, params, &nparams);
- vt100_screen_move_to(
- vt, vt->grid->cur.row + params[0], vt->grid->cur.col, 0);
+ new_row = row + params[0];
+ if (row <= vt->grid->scroll_bottom && new_row > vt->grid->scroll_bottom) {
+ new_row = vt->grid->scroll_bottom;
+ }
+ vt100_screen_move_to(vt, new_row, vt->grid->cur.col);
}
static void vt100_parser_handle_cuf(VT100Screen *vt, char *buf, size_t len)
@@ -2633,8 +2641,7 @@ static void vt100_parser_handle_cuf(VT100Screen *vt, char *buf, size_t len)
DEBUG_TRACE3("CUF", buf + 2, len - 3);
vt100_parser_extract_csi_params(buf + 2, len - 3, params, &nparams);
- vt100_screen_move_to(
- vt, vt->grid->cur.row, vt->grid->cur.col + params[0], 0);
+ vt100_screen_move_to(vt, vt->grid->cur.row, vt->grid->cur.col + params[0]);
}
static void vt100_parser_handle_cub(VT100Screen *vt, char *buf, size_t len)
@@ -2643,8 +2650,7 @@ static void vt100_parser_handle_cub(VT100Screen *vt, char *buf, size_t len)
DEBUG_TRACE3("CUB", buf + 2, len - 3);
vt100_parser_extract_csi_params(buf + 2, len - 3, params, &nparams);
- vt100_screen_move_to(
- vt, vt->grid->cur.row, vt->grid->cur.col - params[0], 0);
+ vt100_screen_move_to(vt, vt->grid->cur.row, vt->grid->cur.col - params[0]);
}
static void vt100_parser_handle_cha(VT100Screen *vt, char *buf, size_t len)
@@ -2653,7 +2659,7 @@ static void vt100_parser_handle_cha(VT100Screen *vt, char *buf, size_t len)
DEBUG_TRACE3("CHA", buf + 2, len - 3);
vt100_parser_extract_csi_params(buf + 2, len - 3, params, &nparams);
- vt100_screen_move_to(vt, vt->grid->cur.row, params[0] - 1, 0);
+ vt100_screen_move_to(vt, vt->grid->cur.row, params[0] - 1);
}
static void vt100_parser_handle_cup(VT100Screen *vt, char *buf, size_t len)
@@ -2668,7 +2674,7 @@ static void vt100_parser_handle_cup(VT100Screen *vt, char *buf, size_t len)
if (params[1] == 0) {
params[1] = 1;
}
- vt100_screen_move_to(vt, params[0] - 1, params[1] - 1, 0);
+ vt100_screen_move_to(vt, params[0] - 1, params[1] - 1);
}
static void vt100_parser_handle_ed(VT100Screen *vt, char *buf, size_t len)
@@ -2803,7 +2809,7 @@ static void vt100_parser_handle_vpa(VT100Screen *vt, char *buf, size_t len)
DEBUG_TRACE3("VPA", buf + 2, len - 3);
vt100_parser_extract_csi_params(buf + 2, len - 3, params, &nparams);
- vt100_screen_move_to(vt, params[0] - 1, vt->grid->cur.col, 0);
+ vt100_screen_move_to(vt, params[0] - 1, vt->grid->cur.col);
}
static void vt100_parser_handle_sm(VT100Screen *vt, char *buf, size_t len)
diff --git a/src/parser.l b/src/parser.l
index 28e63a8..ecfe812 100644
--- a/src/parser.l
+++ b/src/parser.l
@@ -270,7 +270,7 @@ static void vt100_parser_handle_bel(VT100Screen *vt)
static void vt100_parser_handle_bs(VT100Screen *vt)
{
DEBUG_TRACE1("BS");
- vt100_screen_move_to(vt, vt->grid->cur.row, vt->grid->cur.col - 1, 0);
+ vt100_screen_move_to(vt, vt->grid->cur.row, vt->grid->cur.col - 1);
}
static void vt100_parser_handle_tab(VT100Screen *vt)
@@ -278,19 +278,19 @@ static void vt100_parser_handle_tab(VT100Screen *vt)
DEBUG_TRACE1("TAB");
vt100_screen_move_to(
vt, vt->grid->cur.row,
- vt->grid->cur.col - (vt->grid->cur.col % 8) + 8, 0);
+ vt->grid->cur.col - (vt->grid->cur.col % 8) + 8);
}
static void vt100_parser_handle_lf(VT100Screen *vt)
{
DEBUG_TRACE1("LF");
- vt100_screen_move_to(vt, vt->grid->cur.row + 1, vt->grid->cur.col, 1);
+ vt100_screen_move_down_or_scroll(vt);
}
static void vt100_parser_handle_cr(VT100Screen *vt)
{
DEBUG_TRACE1("CR");
- vt100_screen_move_to(vt, vt->grid->cur.row, 0, 0);
+ vt100_screen_move_to(vt, vt->grid->cur.row, 0);
}
static void vt100_parser_handle_deckpam(VT100Screen *vt)
@@ -308,7 +308,7 @@ static void vt100_parser_handle_deckpnm(VT100Screen *vt)
static void vt100_parser_handle_ri(VT100Screen *vt)
{
DEBUG_TRACE1("RI");
- vt100_screen_move_to(vt, vt->grid->cur.row - 1, vt->grid->cur.col, 1);
+ vt100_screen_move_up_or_scroll(vt);
}
static void vt100_parser_handle_ris(VT100Screen *vt)
@@ -317,7 +317,7 @@ static void vt100_parser_handle_ris(VT100Screen *vt)
vt100_screen_use_normal_buffer(vt);
vt100_screen_set_scroll_region(
vt, 0, vt->grid->max.row - 1, 0, vt->grid->max.col - 1);
- vt100_screen_move_to(vt, 0, 0, 0);
+ vt100_screen_move_to(vt, 0, 0);
vt100_screen_clear_screen(vt);
vt100_screen_save_cursor(vt);
vt100_screen_reset_text_attributes(vt);
@@ -406,21 +406,29 @@ static void vt100_parser_handle_ich(VT100Screen *vt, char *buf, size_t len)
static void vt100_parser_handle_cuu(VT100Screen *vt, char *buf, size_t len)
{
int params[VT100_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams;
+ int row = vt->grid->cur.row, new_row;
DEBUG_TRACE3("CUU", buf + 2, len - 3);
vt100_parser_extract_csi_params(buf + 2, len - 3, params, &nparams);
- vt100_screen_move_to(
- vt, vt->grid->cur.row - params[0], vt->grid->cur.col, 0);
+ new_row = row - params[0];
+ if (row >= vt->grid->scroll_top && new_row < vt->grid->scroll_top) {
+ new_row = vt->grid->scroll_top;
+ }
+ vt100_screen_move_to(vt, new_row, vt->grid->cur.col);
}
static void vt100_parser_handle_cud(VT100Screen *vt, char *buf, size_t len)
{
int params[VT100_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams;
+ int row = vt->grid->cur.row, new_row;
DEBUG_TRACE3("CUD", buf + 2, len - 3);
vt100_parser_extract_csi_params(buf + 2, len - 3, params, &nparams);
- vt100_screen_move_to(
- vt, vt->grid->cur.row + params[0], vt->grid->cur.col, 0);
+ new_row = row + params[0];
+ if (row <= vt->grid->scroll_bottom && new_row > vt->grid->scroll_bottom) {
+ new_row = vt->grid->scroll_bottom;
+ }
+ vt100_screen_move_to(vt, new_row, vt->grid->cur.col);
}
static void vt100_parser_handle_cuf(VT100Screen *vt, char *buf, size_t len)
@@ -429,8 +437,7 @@ static void vt100_parser_handle_cuf(VT100Screen *vt, char *buf, size_t len)
DEBUG_TRACE3("CUF", buf + 2, len - 3);
vt100_parser_extract_csi_params(buf + 2, len - 3, params, &nparams);
- vt100_screen_move_to(
- vt, vt->grid->cur.row, vt->grid->cur.col + params[0], 0);
+ vt100_screen_move_to(vt, vt->grid->cur.row, vt->grid->cur.col + params[0]);
}
static void vt100_parser_handle_cub(VT100Screen *vt, char *buf, size_t len)
@@ -439,8 +446,7 @@ static void vt100_parser_handle_cub(VT100Screen *vt, char *buf, size_t len)
DEBUG_TRACE3("CUB", buf + 2, len - 3);
vt100_parser_extract_csi_params(buf + 2, len - 3, params, &nparams);
- vt100_screen_move_to(
- vt, vt->grid->cur.row, vt->grid->cur.col - params[0], 0);
+ vt100_screen_move_to(vt, vt->grid->cur.row, vt->grid->cur.col - params[0]);
}
static void vt100_parser_handle_cha(VT100Screen *vt, char *buf, size_t len)
@@ -449,7 +455,7 @@ static void vt100_parser_handle_cha(VT100Screen *vt, char *buf, size_t len)
DEBUG_TRACE3("CHA", buf + 2, len - 3);
vt100_parser_extract_csi_params(buf + 2, len - 3, params, &nparams);
- vt100_screen_move_to(vt, vt->grid->cur.row, params[0] - 1, 0);
+ vt100_screen_move_to(vt, vt->grid->cur.row, params[0] - 1);
}
static void vt100_parser_handle_cup(VT100Screen *vt, char *buf, size_t len)
@@ -464,7 +470,7 @@ static void vt100_parser_handle_cup(VT100Screen *vt, char *buf, size_t len)
if (params[1] == 0) {
params[1] = 1;
}
- vt100_screen_move_to(vt, params[0] - 1, params[1] - 1, 0);
+ vt100_screen_move_to(vt, params[0] - 1, params[1] - 1);
}
static void vt100_parser_handle_ed(VT100Screen *vt, char *buf, size_t len)
@@ -599,7 +605,7 @@ static void vt100_parser_handle_vpa(VT100Screen *vt, char *buf, size_t len)
DEBUG_TRACE3("VPA", buf + 2, len - 3);
vt100_parser_extract_csi_params(buf + 2, len - 3, params, &nparams);
- vt100_screen_move_to(vt, params[0] - 1, vt->grid->cur.col, 0);
+ vt100_screen_move_to(vt, params[0] - 1, vt->grid->cur.col);
}
static void vt100_parser_handle_sm(VT100Screen *vt, char *buf, size_t len)
diff --git a/src/screen.c b/src/screen.c
index 1dc8f75..afae515 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -170,7 +170,7 @@ void vt100_screen_show_string_ascii(VT100Screen *vt, char *buf, size_t len)
if (col >= vt->grid->max.col) {
vt100_screen_row_at(vt, vt->grid->cur.row)->wrapped = 1;
- vt100_screen_move_to(vt, vt->grid->cur.row + 1, 0, 1);
+ vt100_screen_move_down_or_scroll(vt);
col = 0;
}
cell = vt100_screen_cell_at(vt, vt->grid->cur.row, col++);
@@ -180,7 +180,7 @@ void vt100_screen_show_string_ascii(VT100Screen *vt, char *buf, size_t len)
cell->attrs = vt->attrs;
cell->is_wide = 0;
}
- vt100_screen_move_to(vt, vt->grid->cur.row, col, 0);
+ vt100_screen_move_to(vt, vt->grid->cur.row, col);
}
void vt100_screen_show_string_utf8(VT100Screen *vt, char *buf, size_t len)
@@ -245,7 +245,7 @@ void vt100_screen_show_string_utf8(VT100Screen *vt, char *buf, size_t len)
else {
if (col + (is_wide ? 2 : 1) > vt->grid->max.col) {
vt100_screen_row_at(vt, vt->grid->cur.row)->wrapped = 1;
- vt100_screen_move_to(vt, vt->grid->cur.row + 1, 0, 1);
+ vt100_screen_move_down_or_scroll(vt);
col = 0;
}
cell = vt100_screen_cell_at(vt, vt->grid->cur.row, col);
@@ -263,33 +263,17 @@ void vt100_screen_show_string_utf8(VT100Screen *vt, char *buf, size_t len)
break;
}
}
- vt100_screen_move_to(vt, vt->grid->cur.row, col, 0);
+ vt100_screen_move_to(vt, vt->grid->cur.row, col);
}
-void vt100_screen_move_to(VT100Screen *vt, int row, int col, int scroll)
+void vt100_screen_move_to(VT100Screen *vt, int row, int col)
{
- int top = vt->grid->scroll_top, bottom = vt->grid->scroll_bottom;
-
- if (row > bottom) {
- if (scroll) {
- vt100_screen_scroll_up(vt, row - bottom);
- }
- row = bottom;
- }
- else if (row < top) {
- if (scroll) {
- vt100_screen_scroll_down(vt, top - row);
- }
- row = top;
- }
-
- if (col < 0) {
- col = 0;
- }
-
- if (col >= vt->grid->max.col) {
- col = vt->grid->max.col - 1;
- }
+ row = row < 0 ? 0
+ : row >= vt->grid->max.row ? vt->grid->max.row - 1
+ : row;
+ col = col < 0 ? 0
+ : col >= vt->grid->max.col ? vt->grid->max.col - 1
+ : col;
vt->grid->cur.row = row;
vt->grid->cur.col = col;
@@ -611,6 +595,26 @@ void vt100_screen_scroll_up(VT100Screen *vt, int count)
vt->dirty = 1;
}
+void vt100_screen_move_down_or_scroll(VT100Screen *vt)
+{
+ if (vt->grid->cur.row == vt->grid->scroll_bottom) {
+ vt100_screen_scroll_up(vt, 1);
+ }
+ else {
+ vt100_screen_move_to(vt, vt->grid->cur.row + 1, vt->grid->cur.col);
+ }
+}
+
+void vt100_screen_move_up_or_scroll(VT100Screen *vt)
+{
+ if (vt->grid->cur.row == vt->grid->scroll_top) {
+ vt100_screen_scroll_down(vt, 1);
+ }
+ else {
+ vt100_screen_move_to(vt, vt->grid->cur.row - 1, vt->grid->cur.col);
+ }
+}
+
void vt100_screen_set_scroll_region(
VT100Screen *vt, int top, int bottom, int left, int right)
{
diff --git a/src/screen.h b/src/screen.h
index 8e91c52..3c3da3d 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -122,7 +122,7 @@ void vt100_screen_audible_bell(VT100Screen *vt);
void vt100_screen_visual_bell(VT100Screen *vt);
void vt100_screen_show_string_ascii(VT100Screen *vt, char *buf, size_t len);
void vt100_screen_show_string_utf8(VT100Screen *vt, char *buf, size_t len);
-void vt100_screen_move_to(VT100Screen *vt, int row, int col, int scroll);
+void vt100_screen_move_to(VT100Screen *vt, int row, int col);
void vt100_screen_clear_screen(VT100Screen *vt);
void vt100_screen_clear_screen_forward(VT100Screen *vt);
void vt100_screen_clear_screen_backward(VT100Screen *vt);
@@ -136,6 +136,8 @@ void vt100_screen_delete_lines(VT100Screen *vt, int count);
void vt100_screen_erase_characters(VT100Screen *vt, int count);
void vt100_screen_scroll_down(VT100Screen *vt, int count);
void vt100_screen_scroll_up(VT100Screen *vt, int count);
+void vt100_screen_move_down_or_scroll(VT100Screen *vt);
+void vt100_screen_move_up_or_scroll(VT100Screen *vt);
void vt100_screen_set_scroll_region(
VT100Screen *vt, int top, int bottom, int left, int right);
void vt100_screen_reset_text_attributes(VT100Screen *vt);