termptyesc: support DECCRA + tests

This commit is contained in:
Boris Faure 2018-12-31 19:12:57 +01:00
parent 6661719829
commit 59c547179d
3 changed files with 210 additions and 0 deletions

View File

@ -1967,6 +1967,131 @@ _handle_esc_csi_decera(Termpty *ty, Eina_Unicode **b)
}
}
static void
_handle_esc_csi_deccra(Termpty *ty, Eina_Unicode **b)
{
int top = _csi_arg_get(ty, b);
int left = _csi_arg_get(ty, b);
int bottom = _csi_arg_get(ty, b);
int right = _csi_arg_get(ty, b);
int p1 = _csi_arg_get(ty, b);
int to_top = _csi_arg_get(ty, b);
int to_left = _csi_arg_get(ty, b);
int p2 = _csi_arg_get(ty, b);
int to_bottom = ty->h - 1;
int to_right = ty->w;
int len;
DBG("DECFRA (%d;%d;%d;%d -> %d;%d) Copy Rectangular Area",
top, left, bottom, right, to_top, to_left);
if ((top == -CSI_ARG_ERROR) ||
(left == -CSI_ARG_ERROR) ||
(bottom == -CSI_ARG_ERROR) ||
(right == -CSI_ARG_ERROR) ||
(p1 == -CSI_ARG_ERROR) ||
(to_top == -CSI_ARG_ERROR) ||
(to_left == -CSI_ARG_ERROR) ||
(p2 == -CSI_ARG_ERROR))
return;
if (_clean_up_rect_coordinates(ty, &top, &left, &bottom, &right) < 0)
return;
TERMPTY_RESTRICT_FIELD(to_top, 1, ty->h);
if (ty->termstate.restrict_cursor)
{
to_top += ty->termstate.top_margin;
if (ty->termstate.bottom_margin)
{
if (to_top >= ty->termstate.bottom_margin)
to_top = ty->termstate.bottom_margin;
to_bottom = ty->termstate.bottom_margin - 1;
}
}
to_top--;
if (to_bottom - to_top > bottom - top)
to_bottom = to_top + bottom - top;
TERMPTY_RESTRICT_FIELD(to_left, 1, ty->w);
if (ty->termstate.restrict_cursor)
{
to_left += ty->termstate.left_margin;
if (ty->termstate.right_margin)
{
if (to_left >= ty->termstate.right_margin)
to_left = ty->termstate.right_margin;
to_right = ty->termstate.right_margin;
}
}
to_left--;
len = MIN(right - left, to_right - to_left);
if (to_top < top)
{
/* Up -> Bottom */
for (; top <= bottom && to_top <= to_bottom; top++, to_top++)
{
Termcell *cells_src = &(TERMPTY_SCREEN(ty, left, top));
Termcell *cells_dst = &(TERMPTY_SCREEN(ty, to_left, to_top));
int x;
if (to_left <= left)
{
/* -> */
for (x = 0; x < len; x++)
{
if (&(cells_src[x]) != &(cells_dst[x]))
{
TERMPTY_CELL_COPY(ty, &(cells_src[x]), &(cells_dst[x]), 1);
}
}
}
else
{
/* <- */
for (x = len - 1; x >= 0; x--)
{
if (&(cells_src[x]) != &(cells_dst[x]))
{
TERMPTY_CELL_COPY(ty, &(cells_src[x]), &(cells_dst[x]), 1);
}
}
}
}
}
else
{
/* Bottom -> Up */
for (; bottom >= top && to_bottom >= to_top; bottom--, to_bottom--)
{
Termcell *cells_src = &(TERMPTY_SCREEN(ty, left, bottom));
Termcell *cells_dst = &(TERMPTY_SCREEN(ty, to_left, to_bottom));
int x;
if (to_left <= left)
{
/* -> */
for (x = 0; x < len; x++)
{
if (&(cells_src[x]) != &(cells_dst[x]))
{
TERMPTY_CELL_COPY(ty, &(cells_src[x]), &(cells_dst[x]), 1);
}
}
}
else
{
/* <- */
for (x = len - 1; x >= 0; x--)
{
if (&(cells_src[x]) != &(cells_dst[x]))
{
TERMPTY_CELL_COPY(ty, &(cells_src[x]), &(cells_dst[x]), 1);
}
}
}
}
}
}
static void
_handle_esc_csi_cursor_pos_set(Termpty *ty, Eina_Unicode **b,
const Eina_Unicode *cc)
@ -2704,6 +2829,12 @@ HVP:
case 'u': // restore cursor pos
termpty_cursor_copy(ty, EINA_FALSE);
break;
case 'v':
if (*(cc-1) == '$')
_handle_esc_csi_deccra(ty, &b);
else
ty->decoding_error = EINA_TRUE;
break;
case 'x':
if (*(cc-1) == '$')
_handle_esc_csi_decfra(ty, &b);

78
tests/deccra.sh Executable file
View File

@ -0,0 +1,78 @@
#!/bin/sh
# move to 0; 0
printf '\033[H'
# fill in left space
for _ in $(seq 0 23); do
for _ in $(seq 0 3); do
printf '\033[0;1m\'
printf '\033[0;1m-'
printf '\033[0;46;1;4m/'
printf '\033[0;46;1;4m|'
printf '\033[0;1;4;7m\\'
printf '\033[0m~'
printf '\033[0;1m_'
printf '\033[0;31;7m>'
printf '\033[0;31;4;7m^'
printf '\033[0;1;7m<'
done
for _ in $(seq 0 3); do
printf '\033[0m '
done
done
# move to 0; 0
printf '\033[H'
#set color
printf '\033[43;32;3m'
# set top/bottom margins:
printf '\033[3;20r'
# allow left/right margins
printf '\033[?69h'
# set left/right margins:
printf '\033[5;75s'
# copy one char
printf '\033[3;3;3;3;;2;48;\044v'
# Copy rectangle
printf '\033[5;5;9;9;;8;45;\044v'
# invalid rectangles
printf '\033[5;5;4;9;;8;45;\044v'
printf '\033[5;5;9;4;;8;45;\044v'
# Copy rectangle with invalid page values
printf '\033[5;5;9;9;1337;14;55;1337\044v'
# Copy to part clipped
printf '\033[5;5;9;9;;22;78;\044v'
# Copy upon itself (full overlap)
printf '\033[5;5;9;9;;5;5;\044v'
# Copy upon itself (some overlap on the right)
printf '\033[5;5;9;9;;7;7;\044v'
# Copy upon itself (some overlap on the left)
printf '\033[15;5;19;9;;17;3;\044v'
# WITH MARGINS ENFORCED
# set top/bottom margins:
printf '\033[3;10r'
# allow left/right margins
printf '\033[?69h'
# set left/right margins:
printf '\033[5;60s'
# restrict cursor
printf '\033[?6h'
printf '\033[5;21;9;25;;1;50;\044v'
# Copy rectangle to on margins
printf '\033[5;21;9;25;;6;54;\044v'

View File

@ -51,3 +51,4 @@ decrara-no-rectangular-no-restrict-cursor.sh c375dd5d6538aff4c920b022f32f4ab0
decrara-no-rectangular-restrict-cursor.sh 815a848844cf7ea33d60e71948346a33
decic-decdc.sh 6d67999a7c5c771281ff2229cdbdda76
ich.sh fe1bfee25582f37a27665af1f66513df
deccra.sh 6a0846004c4effb9d5eb45b8044d5f7e