From 242adb20f36a4bc4460f35d1be378427d33f2ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Wed, 6 Jan 2021 21:14:45 +0100 Subject: [PATCH] Terminal: implement ECMA-48 "REP" fix #16724 Change-Id: Ie9f8252393a65a0101a6d78db2360f48bb52bc73 Reviewed-on: https://review.haiku-os.org/c/haiku/+/3607 Reviewed-by: Adrien Destugues --- src/apps/terminal/BasicTerminalBuffer.cpp | 11 ++++++++++- src/apps/terminal/BasicTerminalBuffer.h | 3 +++ src/apps/terminal/TermParse.cpp | 12 ++++++++++++ src/apps/terminal/VTPrsTbl.c | 2 +- src/apps/terminal/VTparse.h | 1 + 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/apps/terminal/BasicTerminalBuffer.cpp b/src/apps/terminal/BasicTerminalBuffer.cpp index 43e3629e2b..06dfd6cad5 100644 --- a/src/apps/terminal/BasicTerminalBuffer.cpp +++ b/src/apps/terminal/BasicTerminalBuffer.cpp @@ -121,7 +121,8 @@ BasicTerminalBuffer::BasicTerminalBuffer() fSavedOriginMode(false), fTabStops(NULL), fEncoding(M_UTF8), - fCaptureFile(-1) + fCaptureFile(-1), + fLast() { } @@ -625,6 +626,7 @@ BasicTerminalBuffer::InsertChar(UTF8Char c) { //debug_printf("BasicTerminalBuffer::InsertChar('%.*s' (%d), %#lx)\n", //(int)c.ByteCount(), c.bytes, c.bytes[0], attributes); + fLast = c; int32 width = c.IsFullWidth() ? FULL_WIDTH : HALF_WIDTH; if (fSoftWrappedCursor || (fCursor.x + width) > fWidth) @@ -1857,4 +1859,11 @@ BasicTerminalBuffer::CaptureChar(char ch) write(fCaptureFile, &ch, 1); } + +void +BasicTerminalBuffer::InsertLastChar() +{ + InsertChar(fLast); +} + #endif diff --git a/src/apps/terminal/BasicTerminalBuffer.h b/src/apps/terminal/BasicTerminalBuffer.h index c1ad050178..418f014a1c 100644 --- a/src/apps/terminal/BasicTerminalBuffer.h +++ b/src/apps/terminal/BasicTerminalBuffer.h @@ -141,6 +141,7 @@ public: void SetInsertMode(int flag); void InsertSpace(int32 num); void InsertLines(int32 numLines); + void InsertLastChar(); // delete chars/lines inline void EraseChars(int32 numChars); @@ -250,6 +251,8 @@ protected: int fEncoding; int fCaptureFile; + UTF8Char fLast; + // listener/dirty region management TerminalBufferDirtyInfo fDirtyInfo; }; diff --git a/src/apps/terminal/TermParse.cpp b/src/apps/terminal/TermParse.cpp index 0a2b71ae9d..d925ade1fc 100644 --- a/src/apps/terminal/TermParse.cpp +++ b/src/apps/terminal/TermParse.cpp @@ -1213,6 +1213,18 @@ TermParse::EscParse() fBuffer->MoveCursorUp(row); parsestate = groundtable; break; + + case CASE_REP: // ESC [...b repeat last graphic char + { + int repetitions = param[0]; + int maxRepetitions = fBuffer->Width() * fBuffer->Height(); + if (repetitions > maxRepetitions) + repetitions = maxRepetitions; + for (int i = 0; i < repetitions; i++) + fBuffer->InsertLastChar(); + parsestate = groundtable; + break; + } default: break; } diff --git a/src/apps/terminal/VTPrsTbl.c b/src/apps/terminal/VTPrsTbl.c index 62e85e9e98..ac43bb9396 100644 --- a/src/apps/terminal/VTPrsTbl.c +++ b/src/apps/terminal/VTPrsTbl.c @@ -1119,7 +1119,7 @@ CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, -CASE_GROUND_STATE, +CASE_REP, CASE_DA1, /* d e f g */ CASE_VPA, diff --git a/src/apps/terminal/VTparse.h b/src/apps/terminal/VTparse.h index b0342a2a6e..c93ab21b77 100644 --- a/src/apps/terminal/VTparse.h +++ b/src/apps/terminal/VTparse.h @@ -101,3 +101,4 @@ #define CASE_CFT 98 #define CASE_INDEX 99 #define CASE_NEXT_LINE 100 +#define CASE_REP 101