termpty: handle IL with left/right margins + tests
This commit is contained in:
parent
571d2d03f1
commit
822f959163
|
@ -89,6 +89,21 @@ _safechar(unsigned int c)
|
||||||
return _str;
|
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 {
|
enum csi_arg_error {
|
||||||
CSI_ARG_NO_VALUE = 1,
|
CSI_ARG_NO_VALUE = 1,
|
||||||
CSI_ARG_ERROR = 2
|
CSI_ARG_ERROR = 2
|
||||||
|
@ -2564,6 +2579,82 @@ _handle_esc_csi_decsel(Termpty *ty, Eina_Unicode **ptr)
|
||||||
_handle_esc_csi_el(ty, 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
|
static int
|
||||||
_handle_esc_csi(Termpty *ty, const Eina_Unicode *c, const Eina_Unicode *ce)
|
_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
|
else
|
||||||
_handle_esc_csi_el(ty, &b);
|
_handle_esc_csi_el(ty, &b);
|
||||||
break;
|
break;
|
||||||
case 'L': // insert N lines - cy
|
case 'L':
|
||||||
EINA_FALLTHROUGH;
|
_handle_esc_csi_il(ty, &b);
|
||||||
case 'M': // delete N lines - cy
|
break;
|
||||||
arg = _csi_arg_get(ty, &b);
|
case 'M':
|
||||||
if (arg == -CSI_ARG_ERROR)
|
_handle_esc_csi_dl(ty, &b);
|
||||||
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;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'P': // erase and scrollback N chars
|
case 'P': // erase and scrollback N chars
|
||||||
_handle_esc_csi_dch(ty, &b);
|
_handle_esc_csi_dch(ty, &b);
|
||||||
|
|
|
@ -99,28 +99,36 @@ termpty_text_scroll_rev(Termpty *ty, Eina_Bool clear)
|
||||||
DBG("... scroll rev!!!!! [%i->%i]", start_y, end_y);
|
DBG("... scroll rev!!!!! [%i->%i]", start_y, end_y);
|
||||||
termio_scroll(ty->obj, 1, 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
|
// screen is a circular buffer now
|
||||||
ty->circular_offset--;
|
ty->circular_offset--;
|
||||||
if (ty->circular_offset < 0)
|
if (ty->circular_offset < 0)
|
||||||
ty->circular_offset = ty->h - 1;
|
ty->circular_offset = ty->h - 1;
|
||||||
|
|
||||||
cells = &(ty->screen[ty->circular_offset * ty->w]);
|
cells = &(ty->screen[ty->circular_offset * ty->w]);
|
||||||
if (clear)
|
if (clear)
|
||||||
termpty_cells_clear(ty, cells, ty->w);
|
termpty_cells_clear(ty, cells, ty->w);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cells = &(TERMPTY_SCREEN(ty, 0, end_y));
|
int x = ty->termstate.left_margin;
|
||||||
for (y = end_y; y > start_y; y--)
|
int w = ty->w - x;
|
||||||
{
|
|
||||||
cells = &(TERMPTY_SCREEN(ty, 0, (y - 1)));
|
if (ty->termstate.right_margin)
|
||||||
cells2 = &(TERMPTY_SCREEN(ty, 0, y));
|
w = ty->termstate.right_margin - x;
|
||||||
TERMPTY_CELL_COPY(ty, cells, cells2, ty->w);
|
|
||||||
}
|
cells = &(TERMPTY_SCREEN(ty, x, end_y));
|
||||||
if (clear)
|
for (y = end_y; y > start_y; y--)
|
||||||
termpty_cells_clear(ty, cells, ty->w);
|
{
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,3 +58,4 @@ ed-2.sh 82e7919a46fdea3a003143b41562b148
|
||||||
ed-3.sh 005871b7e4d63017c08a73ab34f99b14
|
ed-3.sh 005871b7e4d63017c08a73ab34f99b14
|
||||||
ed-4.sh 574f37ac24ead26ef86c03d7dfae3152
|
ed-4.sh 574f37ac24ead26ef86c03d7dfae3152
|
||||||
el.sh abca9d5e5990bed6bd72a7ab9f72b849
|
el.sh abca9d5e5990bed6bd72a7ab9f72b849
|
||||||
|
il.sh 1788258650a94f2568d05f749b6cf578
|
||||||
|
|
Loading…
Reference in New Issue