aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Faure <billiob@gmail.com>2019-01-05 19:25:37 +0100
committerBoris Faure <billiob@gmail.com>2019-01-05 19:25:37 +0100
commit822f95916394c7e3a4aa1560d07f192d404d331a (patch)
tree368b839c50f4187ed083b71c321ae2fc1accdf0f
parentMerge branch 'terminology-1.3' (diff)
downloadterminology-822f95916394c7e3a4aa1560d07f192d404d331a.tar.gz
termpty: handle IL with left/right margins + tests
-rw-r--r--src/bin/termptyesc.c133
-rw-r--r--src/bin/termptyops.c40
-rw-r--r--tests/tests.results1
3 files changed, 121 insertions, 53 deletions
diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c
index b70fe89..477826c 100644
--- a/src/bin/termptyesc.c
+++ b/src/bin/termptyesc.c
@@ -89,6 +89,21 @@ _safechar(unsigned int c)
return _str;
}
+static Eina_Bool
+_cursor_is_within_margins(const Termpty *ty)
+{
+ return !(
+ ((ty->termstate.top_margin > 0)
+ && (ty->cursor_state.cy < ty->termstate.top_margin))
+ || ((ty->termstate.bottom_margin > 0)
+ && (ty->cursor_state.cy >= ty->termstate.bottom_margin))
+ || ((ty->termstate.left_margin > 0)
+ && (ty->cursor_state.cx < ty->termstate.left_margin))
+ || ((ty->termstate.right_margin > 0)
+ && (ty->cursor_state.cx >= ty->termstate.right_margin))
+ );
+}
+
enum csi_arg_error {
CSI_ARG_NO_VALUE = 1,
CSI_ARG_ERROR = 2
@@ -2564,6 +2579,82 @@ _handle_esc_csi_decsel(Termpty *ty, Eina_Unicode **ptr)
_handle_esc_csi_el(ty, ptr);
}
+static void
+_handle_esc_csi_il(Termpty *ty, Eina_Unicode **ptr)
+{
+ Eina_Unicode *b = *ptr;
+ int arg = _csi_arg_get(ty, &b);
+ int sy1, sy2, i;
+
+ if (arg == -CSI_ARG_ERROR)
+ return;
+
+ TERMPTY_RESTRICT_FIELD(arg, 1, ty->h);
+ DBG("IL - Insert Lines: %d", arg);
+
+ if (!_cursor_is_within_margins(ty))
+ return;
+
+ sy1 = ty->termstate.top_margin;
+ sy2 = ty->termstate.bottom_margin;
+ if (ty->termstate.bottom_margin == 0)
+ {
+ ty->termstate.top_margin = ty->cursor_state.cy;
+ ty->termstate.bottom_margin = ty->h;
+ }
+ else
+ {
+ ty->termstate.top_margin = ty->cursor_state.cy;
+ if (ty->termstate.bottom_margin <= ty->termstate.top_margin)
+ ty->termstate.bottom_margin = ty->termstate.top_margin + 1;
+ }
+ ERR("arg:%d", arg);
+ for (i = 0; i < arg; i++)
+ {
+ termpty_text_scroll_rev(ty, EINA_TRUE);
+ }
+ ty->termstate.top_margin = sy1;
+ ty->termstate.bottom_margin = sy2;
+ ty->cursor_state.cx = ty->termstate.left_margin;
+}
+
+static void
+_handle_esc_csi_dl(Termpty *ty, Eina_Unicode **ptr)
+{
+ Eina_Unicode *b = *ptr;
+ int arg = _csi_arg_get(ty, &b);
+ int sy1, sy2, i;
+
+ if (arg == -CSI_ARG_ERROR)
+ return;
+
+ TERMPTY_RESTRICT_FIELD(arg, 1, ty->h);
+ DBG("DL - Delete Lines: %d", arg);
+
+ if (!_cursor_is_within_margins(ty))
+ return;
+
+ sy1 = ty->termstate.top_margin;
+ sy2 = ty->termstate.bottom_margin;
+ if (ty->termstate.bottom_margin == 0)
+ {
+ ty->termstate.top_margin = ty->cursor_state.cy;
+ ty->termstate.bottom_margin = ty->h;
+ }
+ else
+ {
+ ty->termstate.top_margin = ty->cursor_state.cy;
+ if (ty->termstate.bottom_margin <= ty->termstate.top_margin)
+ ty->termstate.bottom_margin = ty->termstate.top_margin + 1;
+ }
+ for (i = 0; i < arg; i++)
+ {
+ termpty_text_scroll(ty, EINA_TRUE);
+ }
+ ty->termstate.top_margin = sy1;
+ ty->termstate.bottom_margin = sy2;
+}
+
static int
_handle_esc_csi(Termpty *ty, const Eina_Unicode *c, const Eina_Unicode *ce)
{
@@ -2638,43 +2729,11 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, const Eina_Unicode *ce)
else
_handle_esc_csi_el(ty, &b);
break;
- case 'L': // insert N lines - cy
- EINA_FALLTHROUGH;
- case 'M': // delete N lines - cy
- arg = _csi_arg_get(ty, &b);
- if (arg == -CSI_ARG_ERROR)
- goto error;
- TERMPTY_RESTRICT_FIELD(arg, 1, ty->h);
- DBG("%s %d lines", (*cc == 'M') ? "delete" : "insert", arg);
- if ((ty->cursor_state.cy >= ty->termstate.top_margin) &&
- ((ty->termstate.bottom_margin == 0) ||
- (ty->cursor_state.cy < ty->termstate.bottom_margin)))
- {
- int sy1, sy2;
-
- sy1 = ty->termstate.top_margin;
- sy2 = ty->termstate.bottom_margin;
- if (ty->termstate.bottom_margin == 0)
- {
- ty->termstate.top_margin = ty->cursor_state.cy;
- ty->termstate.bottom_margin = ty->h;
- }
- else
- {
- ty->termstate.top_margin = ty->cursor_state.cy;
- if (ty->termstate.bottom_margin <= ty->termstate.top_margin)
- ty->termstate.bottom_margin = ty->termstate.top_margin + 1;
- }
- for (i = 0; i < arg; i++)
- {
- if (*cc == 'M')
- termpty_text_scroll(ty, EINA_TRUE);
- else
- termpty_text_scroll_rev(ty, EINA_TRUE);
- }
- ty->termstate.top_margin = sy1;
- ty->termstate.bottom_margin = sy2;
- }
+ case 'L':
+ _handle_esc_csi_il(ty, &b);
+ break;
+ case 'M':
+ _handle_esc_csi_dl(ty, &b);
break;
case 'P': // erase and scrollback N chars
_handle_esc_csi_dch(ty, &b);
diff --git a/src/bin/termptyops.c b/src/bin/termptyops.c
index f0dfd04..6b7bc9e 100644
--- a/src/bin/termptyops.c
+++ b/src/bin/termptyops.c
@@ -99,28 +99,36 @@ termpty_text_scroll_rev(Termpty *ty, Eina_Bool clear)
DBG("... scroll rev!!!!! [%i->%i]", start_y, end_y);
termio_scroll(ty->obj, 1, start_y, end_y);
- if (start_y == 0 && end_y == ty->h - 1)
+ if ((start_y == 0 && end_y == (ty->h - 1)) &&
+ (ty->termstate.left_margin == 0) &&
+ (ty->termstate.right_margin == 0))
{
- // screen is a circular buffer now
- ty->circular_offset--;
- if (ty->circular_offset < 0)
- ty->circular_offset = ty->h - 1;
+ // screen is a circular buffer now
+ ty->circular_offset--;
+ if (ty->circular_offset < 0)
+ ty->circular_offset = ty->h - 1;
- cells = &(ty->screen[ty->circular_offset * ty->w]);
- if (clear)
+ cells = &(ty->screen[ty->circular_offset * ty->w]);
+ if (clear)
termpty_cells_clear(ty, cells, ty->w);
}
else
{
- cells = &(TERMPTY_SCREEN(ty, 0, end_y));
- for (y = end_y; y > start_y; y--)
- {
- cells = &(TERMPTY_SCREEN(ty, 0, (y - 1)));
- cells2 = &(TERMPTY_SCREEN(ty, 0, y));
- TERMPTY_CELL_COPY(ty, cells, cells2, ty->w);
- }
- if (clear)
- termpty_cells_clear(ty, cells, ty->w);
+ int x = ty->termstate.left_margin;
+ int w = ty->w - x;
+
+ if (ty->termstate.right_margin)
+ w = ty->termstate.right_margin - x;
+
+ cells = &(TERMPTY_SCREEN(ty, x, end_y));
+ for (y = end_y; y > start_y; y--)
+ {
+ cells = &(TERMPTY_SCREEN(ty, x, (y - 1)));
+ cells2 = &(TERMPTY_SCREEN(ty, x, y));
+ TERMPTY_CELL_COPY(ty, cells, cells2, w);
+ }
+ if (clear)
+ termpty_cells_clear(ty, cells, w);
}
}
diff --git a/tests/tests.results b/tests/tests.results
index e064dae..781f511 100644
--- a/tests/tests.results
+++ b/tests/tests.results
@@ -58,3 +58,4 @@ ed-2.sh 82e7919a46fdea3a003143b41562b148
ed-3.sh 005871b7e4d63017c08a73ab34f99b14
ed-4.sh 574f37ac24ead26ef86c03d7dfae3152
el.sh abca9d5e5990bed6bd72a7ab9f72b849
+il.sh 1788258650a94f2568d05f749b6cf578