diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c index e6c64100..7ee62815 100644 --- a/src/bin/termptyesc.c +++ b/src/bin/termptyesc.c @@ -1661,6 +1661,88 @@ _handle_esc_csi_deccara(Termpty *ty, Eina_Unicode **ptr, } } +static void +_handle_esc_csi_decrara(Termpty *ty, Eina_Unicode **ptr, + const Eina_Unicode * const end) +{ + Eina_Unicode *b = *ptr; + int top; + int left; + int bottom; + int right; + int i, len; + Eina_Bool reverse_bold = EINA_FALSE; + Eina_Bool reverse_underline = EINA_FALSE; + Eina_Bool reverse_blink = EINA_FALSE; + Eina_Bool reverse_inverse = EINA_FALSE; + + top = _csi_arg_get(ty, &b); + left = _csi_arg_get(ty, &b); + bottom = _csi_arg_get(ty, &b); + right = _csi_arg_get(ty, &b); + + DBG("DECRARA (%d;%d;%d;%d) Reverse Attributes in Rectangular Area", + top, left, bottom, right); + if ((top == -CSI_ARG_ERROR) || + (left == -CSI_ARG_ERROR) || + (bottom == -CSI_ARG_ERROR) || + (right == -CSI_ARG_ERROR)) + return; + + while (b && b < end) + { + int arg = _csi_arg_get(ty, &b); + switch (arg) + { + case -CSI_ARG_ERROR: + return; + case -CSI_ARG_NO_VALUE: + EINA_FALLTHROUGH; + case 0: + reverse_bold = reverse_underline = reverse_blink = reverse_inverse = EINA_TRUE; + break; + case 1: + reverse_bold = EINA_TRUE; + break; + case 4: + reverse_underline = EINA_TRUE; + break; + case 5: + reverse_blink = EINA_TRUE; + break; + case 7: + reverse_inverse = EINA_TRUE; + break; + default: + WRN("Invalid change attribute [%i]", arg); + ty->decoding_error = EINA_TRUE; + return; + } + } + + if (_clean_up_rect_coordinates(ty, &top, &left, &bottom, &right) < 0) + return; + + len = right - left; + + for (; top <= bottom; top++) + { + Termcell *cells = &(TERMPTY_SCREEN(ty, left, top)); + for (i = 0; i < len; i++) + { + Termatt * att = &cells[i].att; + if (reverse_bold) + att->bold = !att->bold; + if (reverse_underline) + att->underline = !att->underline; + if (reverse_blink) + att->blink = !att->blink; + if (reverse_inverse) + att->inverse = !att->inverse; + } + } +} + static void _handle_esc_csi_decera(Termpty *ty, Eina_Unicode **b) { @@ -2266,12 +2348,17 @@ HVP: termpty_cursor_copy(ty, EINA_TRUE); } break; - case 't': // window manipulation - arg = _csi_arg_get(ty, &b); - if (arg == -CSI_ARG_ERROR) - goto error; - WRN("TODO: window operation %d not supported", arg); - ty->decoding_error = EINA_TRUE; + case 't': + if (*(cc-1) == '$') + _handle_esc_csi_decrara(ty, &b, be-1); + else + { + arg = _csi_arg_get(ty, &b); + if (arg == -CSI_ARG_ERROR) + goto error; + WRN("TODO: window operation %d not supported", arg); + ty->decoding_error = EINA_TRUE; + } break; case 'u': // restore cursor pos termpty_cursor_copy(ty, EINA_FALSE); diff --git a/tests/decrara-rectangular-no-restrict-cursor.sh b/tests/decrara-rectangular-no-restrict-cursor.sh new file mode 100755 index 00000000..982feba0 --- /dev/null +++ b/tests/decrara-rectangular-no-restrict-cursor.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +# move to 0; 0 +printf '\033[H' +# fill space +PL=0 +for _ in $(seq 0 23); do + PL=$((PL+1)) + if [ $PL -ge 9 ] ; then + PL=0 + fi + for _ in $(seq 1 $PL); do + printf '#' + done + PR=$((10 - PL)) + for _ in $(seq 0 6); do + printf '\033[0;1m\-' + printf '\033[0;46;1;4m/' + printf '\033[0;46;1;4;5m|' + printf '\033[0;1;4;5;7m\\' + printf '\033[0m~' + printf '\033[0;1;5m_' + printf '\033[0;31;5;7m>' + printf '\033[0;31;4;7m^' + printf '\033[0;1;7m<' + done + printf '\033[0m' + for _ in $(seq 1 $PR); do + printf '#' + done +done + +# move to 0; 0 +printf '\033[H' + +# set top/bottom margins: +printf '\033[5;20r' + +# force rectangular modifications +printf '\033[2*x' + +# reset all +printf '\033[1;10;80;15;0\044t' + +# reset all +printf '\033[1;20;80;25;1;4;5;7\044t' + +# reverse bold/blink +printf '\033[1;30;80;35;1;5\044t' + +# reverse bold/underline +printf '\033[1;40;80;45;1;4\044t' + +# reverse blink/inverse +printf '\033[1;50;80;55;5;7\044t' + +# reverse underline/inverse +printf '\033[1;60;80;65;4;7;0\044t' diff --git a/tests/decrara-rectangular-restrict-cursor.sh b/tests/decrara-rectangular-restrict-cursor.sh new file mode 100755 index 00000000..d5f8f9a9 --- /dev/null +++ b/tests/decrara-rectangular-restrict-cursor.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +# move to 0; 0 +printf '\033[H' +# fill space +PL=0 +for _ in $(seq 0 23); do + PL=$((PL+1)) + if [ $PL -ge 9 ] ; then + PL=0 + fi + for _ in $(seq 1 $PL); do + printf '#' + done + PR=$((10 - PL)) + for _ in $(seq 0 6); do + printf '\033[0;1m\-' + printf '\033[0;46;1;4m/' + printf '\033[0;46;1;4;5m|' + printf '\033[0;1;4;5;7m\\' + printf '\033[0m~' + printf '\033[0;1;5m_' + printf '\033[0;31;5;7m>' + printf '\033[0;31;4;7m^' + printf '\033[0;1;7m<' + done + printf '\033[0m' + for _ in $(seq 1 $PR); do + printf '#' + done +done + +# move to 0; 0 +printf '\033[H' + +# set top/bottom margins: +printf '\033[5;20r' + +# restrict cursor +printf '\033[?6h' + +# force rectangular modifications +printf '\033[2*x' + +# reset all +printf '\033[1;10;80;15;0\044t' + +# reset all +printf '\033[1;20;80;25;1;4;5;7\044t' + +# reverse bold/blink +printf '\033[1;30;80;35;1;5\044t' + +# reverse bold/underline +printf '\033[1;40;80;45;1;4\044t' + +# reverse blink/inverse +printf '\033[1;50;80;55;5;7\044t' + +# reverse underline/inverse +printf '\033[1;60;80;65;4;7;0\044t' diff --git a/tests/tests.results b/tests/tests.results index c46ce8ae..856cd018 100644 --- a/tests/tests.results +++ b/tests/tests.results @@ -43,3 +43,5 @@ decbi.sh 8153bff12a0d529cb8ba0dbff036a1ee decfi.sh e93690447902b923d3d9d2ae72a31de4 deccara-rectangular-no-restrict-cursor.sh 0d04ff5f4a266917528ff8d17846c18a deccara-rectangular-restrict-cursor.sh 9f23ac6a3423ba8bf7b8af5116e2843b +decrara-rectangular-no-restrict-cursor.sh be9836ff18eafb90795faecc042f34d6 +decrara-rectangular-restrict-cursor.sh e98723f8f749e4902f7f4aaa677b85d6