From 4493cf58800c6c9b145f07551922fdbd030d408d Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 10 Sep 2013 08:36:12 +0800 Subject: [PATCH] Usermode/GUI Terminal - Fixed scroll behavior and early frees --- .../Applications/gui_terminal_src/display.c | 50 +++++++++++-------- Usermode/Applications/gui_terminal_src/main.c | 4 +- .../Applications/gui_terminal_src/vt100.c | 21 +++++++- 3 files changed, 53 insertions(+), 22 deletions(-) diff --git a/Usermode/Applications/gui_terminal_src/display.c b/Usermode/Applications/gui_terminal_src/display.c index 340cbecf..ab39f9ff 100644 --- a/Usermode/Applications/gui_terminal_src/display.c +++ b/Usermode/Applications/gui_terminal_src/display.c @@ -59,6 +59,9 @@ struct sTerminal { struct sLine *AltBuf; }; +// === PROTOTYPES === +void Display_int_SetCursor(tTerminal *Term, int Row, int Col); + // === GLOBALS === tTerminal gMainBuffer; int giCurrentLine; @@ -142,6 +145,8 @@ size_t Display_int_PushCharacter(tTerminal *Term, size_t AvailLength, const char lineptr->Size = newsize; void *tmp = realloc(lineptr->Data, lineptr->Size); if( !tmp ) perror("Display_int_PushCharacter - realloc"); + //_SysDebug("realloc gave %p from %p for line %i", tmp, lineptr->Data, + // Term->CursorRow); lineptr->Data = tmp; } } @@ -206,11 +211,11 @@ void Display_Newline(tTerminal *Term, bool bCarriageReturn) } else { // Don't go down a line - Term->CursorRow --; } } else { // No scroll needed + Term->CursorRow ++; } } else @@ -218,8 +223,10 @@ void Display_Newline(tTerminal *Term, bool bCarriageReturn) if( Term->CursorRow == Term->TotalLines-1 ) { Display_ScrollDown(Term, 1); } + else { + Term->CursorRow ++; + } } - Term->CursorRow ++; if( bCarriageReturn ) { @@ -279,17 +286,13 @@ void Display_ScrollDown(tTerminal *Term, int Count) buffer += top; - if( Term->CursorRow >= top && Term->CursorRow < top+max ) { - Term->CursorRow -= Count; - Term->CursorRow = MAX(Term->CursorRow, top); - Term->CursorRow = MIN(Term->CursorRow, top+max); - } - int clear_top, clear_max; if( Count < 0 ) { // -ve: Scroll up, move buffer contents down Count = -Count; + for( int i = max-Count; i < max; i ++ ) + free(buffer[i].Data); memmove(buffer+Count, buffer, (max-Count)*sizeof(*buffer)); clear_top = 0; @@ -297,6 +300,8 @@ void Display_ScrollDown(tTerminal *Term, int Count) } else { + for( int i = 0; i < Count; i ++ ) + free(buffer[i].Data); memmove(buffer, buffer+Count, (max-Count)*sizeof(*buffer)); clear_top = max-Count; clear_max = max; @@ -304,16 +309,14 @@ void Display_ScrollDown(tTerminal *Term, int Count) // Clear exposed lines for( int i = clear_top; i < clear_max; i ++ ) { - free(buffer[i].Data); buffer[i].Data = NULL; buffer[i].Len = 0; buffer[i].Size = 0; buffer[i].IsDirty = true; - if( Term->CursorRow == i ) { - Term->CursorCol = 0; - Term->CursorByte = 0; - } } + // TODO: Send scroll command to GUI + + Display_int_SetCursor(Term, Term->CursorRow, Term->CursorCol); } void Display_SetCursor(tTerminal *Term, int Row, int Col) @@ -329,23 +332,30 @@ void Display_SetCursor(tTerminal *Term, int Row, int Col) // NOTE: This may be interesting outside of AltBuffer Term->CursorRow = Row; - + + Display_int_SetCursor(Term, Row, Col); +} +void Display_int_SetCursor(tTerminal *Term, int Row, int Col) +{ tLine *line = Display_int_GetCurLine(Term); size_t ofs = 0; - for( int i = 0; i < Col; i ++ ) + int i; + for( i = 0; i < Col; i ++ ) { size_t clen = _GetCharLength(line->Len-ofs, line->Data+ofs, NULL); if( clen == 0 ) { - // TODO: Should moving the cursor up to an unoccupied cell cause a jump? - Col = i; break; } ofs += clen; } - - Term->CursorCol = Col; + Term->CursorCol = i; Term->CursorByte = ofs; + // Move to exactly the column specified + for( ; i < Col; i ++ ) { + Display_int_PushCharacter(Term, 1, " "); + Term->CursorCol ++; + } } void Display_MoveCursor(tTerminal *Term, int RelRow, int RelCol) @@ -459,7 +469,7 @@ void Display_Flush(tTerminal *Term) // Swapping buffers should cause a full resend if( !Term->bHaveSwappedBuffers && !lineptr->IsDirty ) continue; - _SysDebug("Line %i+%i '%.*s'", viewOfs, i, lineptr->Len, lineptr->Data); + _SysDebug("Line %i+%i %p '%.*s'", viewOfs, i, lineptr->Data, lineptr->Len, lineptr->Data); AxWin3_RichText_SendLine(gMainWindow, viewOfs + i, lineptr->Data ? lineptr->Data : "" ); lineptr->IsDirty = 0; diff --git a/Usermode/Applications/gui_terminal_src/main.c b/Usermode/Applications/gui_terminal_src/main.c index 822f28b8..b8f149a6 100644 --- a/Usermode/Applications/gui_terminal_src/main.c +++ b/Usermode/Applications/gui_terminal_src/main.c @@ -102,7 +102,7 @@ int main(int argc, char *argv[], const char **envp) { _SysDebug("Activity on child stdout"); // Read and update screen - char buf[128]; + char buf[512]; int len = _SysRead(giPTYHandle, buf, sizeof(buf)); if( len <= 0 ) break; @@ -189,6 +189,8 @@ void Term_HandleOutput(tTerminal *Term, int Len, const char *Buf) { // TODO: Handle graphical / accelerated modes + //_SysDebug("Term_HandleOutput: %i \"%.*s\"", Len, Len, Buf); + int ofs = 0; int esc_len = 0; diff --git a/Usermode/Applications/gui_terminal_src/vt100.c b/Usermode/Applications/gui_terminal_src/vt100.c index 2f473a9a..4bc0495a 100644 --- a/Usermode/Applications/gui_terminal_src/vt100.c +++ b/Usermode/Applications/gui_terminal_src/vt100.c @@ -37,10 +37,17 @@ int Term_HandleVT100(tTerminal *Term, int Len, const char *Buf) { // Handle VT100 (like) escape sequence int new_bytes = min(MAX_VT100_ESCAPE_LEN - inc_len, Len); - int ret = 0, old_inc_len = inc_len; + int ret = 0; + int old_inc_len = inc_len; memcpy(inc_buf + inc_len, Buf, new_bytes); + if( new_bytes == 0 ) { + inc_len = 0; + return 0; + } + inc_len += new_bytes; + //_SysDebug("inc_buf = %i '%.*s'", inc_len, inc_len, inc_buf); if( inc_len <= 1 ) return 1; // Skip 1 character (the '\x1b') @@ -53,6 +60,14 @@ int Term_HandleVT100(tTerminal *Term, int Len, const char *Buf) ret += 2; } break; + case 'D': + Display_ScrollDown(Term, 1); + ret = 2; + break; + case 'M': + Display_ScrollDown(Term, -1); + ret = 2; + break; default: ret = 2; break; @@ -61,8 +76,12 @@ int Term_HandleVT100(tTerminal *Term, int Len, const char *Buf) if( ret != 0 ) { inc_len = 0; assert(ret > old_inc_len); + //_SysDebug("%i bytes of escape code '%.*s' (return %i)", + // ret, ret, inc_buf, ret-old_inc_len); ret -= old_inc_len; // counter cached bytes } + else + ret = new_bytes; return ret; } -- 2.20.1