aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Faure <billiob@gmail.com>2018-12-31 19:12:57 +0100
committerBoris Faure <billiob@gmail.com>2019-01-01 18:12:06 +0100
commit59c547179d5009a1e6d0c0e7ac4c3be1acb78e3f (patch)
treebf5ade1fffeb21afd1bf2806e15fc38f4e9dd04a
parenttermptyesc: extract ICH to its own function and add tests (diff)
downloadterminology-59c547179d5009a1e6d0c0e7ac4c3be1acb78e3f.tar.gz
termptyesc: support DECCRA + tests
-rw-r--r--src/bin/termptyesc.c131
-rwxr-xr-xtests/deccra.sh78
-rw-r--r--tests/tests.results1
3 files changed, 210 insertions, 0 deletions
diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c
index 5b8444e..e52fe42 100644
--- a/src/bin/termptyesc.c
+++ b/src/bin/termptyesc.c
@@ -1968,6 +1968,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);
diff --git a/tests/deccra.sh b/tests/deccra.sh
new file mode 100755
index 0000000..c8e9079
--- /dev/null
+++ b/tests/deccra.sh
@@ -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'
diff --git a/tests/tests.results b/tests/tests.results
index 324b8ea..0a5e0f7 100644
--- a/tests/tests.results
+++ b/tests/tests.results
@@ -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