X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Fdrv%2Fvterm_termbuf.c;h=1a14f8252ab8481f45c3c477e36df1f4336ab7eb;hb=8b72370eae1a3cfa8916136fd8ffc1460e9291ba;hp=cb0de748635fd1da7ddf359a96eebf305353e3ef;hpb=0247bf719b9a610776747221b8ed4c1343f5c93a;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/drv/vterm_termbuf.c b/KernelLand/Kernel/drv/vterm_termbuf.c index cb0de748..1a14f825 100644 --- a/KernelLand/Kernel/drv/vterm_termbuf.c +++ b/KernelLand/Kernel/drv/vterm_termbuf.c @@ -25,6 +25,7 @@ extern int Term_HandleVT100(tVTerm *Term, int Len, const char *Buf); */ void VT_int_PutString(tVTerm *Term, const Uint8 *Buffer, Uint Count) { + ENTER("pTerm pBuffer iCount", Term, Buffer, Count); // Iterate for( int ofs = 0; ofs < Count; ) { @@ -43,7 +44,9 @@ void VT_int_PutString(tVTerm *Term, const Uint8 *Buffer, Uint Count) ofs += esc_len; } // Update Screen - VT_int_UpdateScreen( Term, 1 ); + LOG("Update"); + VT_int_UpdateScreen( Term, 0 ); + LEAVE('-'); } void VT_int_PutRawString(tVTerm *Term, const Uint8 *String, size_t Bytes) @@ -62,39 +65,75 @@ void VT_int_PutRawString(tVTerm *Term, const Uint8 *String, size_t Bytes) void VT_int_PutChar(tVTerm *Term, Uint32 Ch) { int i; - tVT_Char *buffer; - int write_pos; - int limit; HEAP_VALIDATE(); - if(Term->Flags & VT_FLAG_ALTBUF) { - buffer = Term->AltBuf; - write_pos = Term->AltWritePos; - limit = Term->TextHeight * Term->TextWidth; + const size_t maxrows = VT_int_GetBufferRows(Term); + const size_t limit = maxrows * Term->TextWidth; + tVT_Pos *wrpos = VT_int_GetWritePosPtr(Term); + tVT_Char *buffer = (Term->Flags & VT_FLAG_ALTBUF ? Term->AltBuf : Term->Text); + + // If writing with the cursor on righthand edge, wrap down to next line + // TODO: Wrap to same line? + if( wrpos->Col >= Term->TextWidth ) + { + ASSERTC(wrpos->Col, <=, Term->TextWidth); + VT_int_UpdateScreen( Term, 0 ); + wrpos->Row ++; + wrpos->Col = 0; } - else { - buffer = Term->Text; - write_pos = Term->WritePos; - limit = Term->TextHeight*(giVT_Scrollback+1) * Term->TextWidth; + + // Scroll entire buffer (about to write outside limit) + if( wrpos->Row >= maxrows ) + { + ASSERTC(wrpos->Row, <, maxrows + 1); + VT_int_ScrollText(Term, 1); + wrpos->Row --; } - - // TODO: Can the write position be equal to the end of screen? + + // Bring written cell into view + if( !(Term->Flags & VT_FLAG_ALTBUF) ) + { + if( wrpos->Row >= Term->ViewTopRow + Term->TextHeight ) + { + size_t new_pos = wrpos->Row - (Term->TextHeight - 1); + size_t count = new_pos - Term->ViewTopRow; + VT_int_ScrollFramebuffer(Term, count); + //Debug("VT_int_PutChar: VScroll down to %i", new_pos); + Term->ViewTopRow = new_pos; + } + else if( wrpos->Row < Term->ViewTopRow ) + { + size_t new_pos = wrpos->Row; + size_t count = Term->ViewTopRow - new_pos; + VT_int_ScrollFramebuffer(Term, -count); + //Debug("VT_int_PutChar: VScroll up to %i", new_pos); + Term->ViewTopRow = new_pos; + } + else + { + // no action, cell is visible + } + } + + size_t write_pos = wrpos->Row * Term->TextWidth + wrpos->Col; ASSERTC(write_pos, <, limit); - + switch(Ch) { case '\0': // Ignore NULL byte return; case '\n': + LOG("Newline, update @ %i", write_pos); VT_int_UpdateScreen( Term, 0 ); // Update the line before newlining - write_pos += Term->TextWidth; + wrpos->Row ++; + // TODO: Force scroll? case '\r': - write_pos -= write_pos % Term->TextWidth; + wrpos->Col = 0; break; case '\t': { - size_t col = write_pos % Term->TextWidth; + size_t col = wrpos->Col; do { buffer[ write_pos ].Ch = '\0'; buffer[ write_pos ].Colour = Term->CurColour; @@ -123,89 +162,56 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch) } while(write_pos && i-- && buffer[ write_pos ].Ch == '\0'); if(buffer[ write_pos ].Ch != '\0') write_pos ++; + wrpos->Col = write_pos % Term->TextWidth; break; default: buffer[ write_pos ].Ch = Ch; buffer[ write_pos ].Colour = Term->CurColour; // Update the line before wrapping - if( (write_pos + 1) % Term->TextWidth == 0 ) + if( (write_pos + 1) % Term->TextWidth == 0 ) { + LOG("Line wrap, update @ %i", write_pos); VT_int_UpdateScreen( Term, 0 ); + // NOTE: Code at the top of PutChar handles the actual wrapping + } + wrpos->Col ++; write_pos ++; break; } - if(Term->Flags & VT_FLAG_ALTBUF) - { - Term->AltWritePos = write_pos; - - if(Term->AltWritePos >= limit) - { - Term->AltWritePos -= Term->TextWidth; - VT_int_ScrollText(Term, 1); - } - } - else - { - Term->WritePos = write_pos; - // Move Screen - // - Check if we need to scroll the entire scrollback buffer - if(Term->WritePos >= limit) - { - int base; - - // Update view position - base = Term->TextWidth*Term->TextHeight*(giVT_Scrollback); - if(Term->ViewPos < base) - Term->ViewPos += Term->Width; - if(Term->ViewPos > base) - Term->ViewPos = base; - - VT_int_ScrollText(Term, 1); - Term->WritePos -= Term->TextWidth; - } - // Ok, so we only need to scroll the screen - else if(Term->WritePos >= Term->ViewPos + Term->TextWidth*Term->TextHeight) - { - VT_int_ScrollFramebuffer( Term, 1 ); - - Term->ViewPos += Term->TextWidth; - } - } + ASSERTC(write_pos, <=, limit); HEAP_VALIDATE(); - //LEAVE('-'); + // TODO: Schedule a delayed screen update } void VT_int_ScrollText(tVTerm *Term, int Count) { + ENTER("pTerm iCount", Term, Count); tVT_Char *buf; - int *write_pos_ptr; - int height; int scroll_top, scroll_height; HEAP_VALIDATE(); // Get buffer pointer and attributes + size_t height = VT_int_GetBufferRows(Term); + tVT_Pos *wrpos = VT_int_GetWritePosPtr(Term); + if( Term->Flags & VT_FLAG_ALTBUF ) { buf = Term->AltBuf; - height = Term->TextHeight; - write_pos_ptr = &Term->AltWritePos; scroll_top = Term->ScrollTop; scroll_height = Term->ScrollHeight; } else { buf = Term->Text; - height = Term->TextHeight*(giVT_Scrollback+1); - write_pos_ptr = &Term->WritePos; scroll_top = 0; scroll_height = height; } - const int init_write_pos = *write_pos_ptr; + const tVT_Pos init_wrpos = *wrpos; // Scroll text upwards (more space at bottom) if( Count > 0 ) @@ -231,13 +237,13 @@ void VT_int_ScrollText(tVTerm *Term, int Count) // Update Screen VT_int_ScrollFramebuffer( Term, Count ); if( Term->Flags & VT_FLAG_ALTBUF ) - Term->AltWritePos = base; + wrpos->Row = scroll_top; else - Term->WritePos = Term->ViewPos + Term->TextWidth*(Term->TextHeight - Count); + wrpos->Row = Term->ViewTopRow + (Term->TextHeight - Count); for( int i = 0; i < Count; i ++ ) { VT_int_UpdateScreen( Term, 0 ); - *write_pos_ptr += Term->TextWidth; + wrpos->Row ++; } } else @@ -263,18 +269,20 @@ void VT_int_ScrollText(tVTerm *Term, int Count) // Update screen (shift framebuffer, re-render revealed lines) VT_int_ScrollFramebuffer( Term, -Count ); if( Term->Flags & VT_FLAG_ALTBUF ) - Term->AltWritePos = Term->TextWidth*scroll_top; + wrpos->Row = scroll_top; else - Term->WritePos = Term->ViewPos; + wrpos->Row = Term->ViewTopRow; for( int i = 0; i < Count; i ++ ) { VT_int_UpdateScreen( Term, 0 ); + // Increment? } } - *write_pos_ptr = init_write_pos; + *wrpos = init_wrpos; HEAP_VALIDATE(); + LEAVE('-'); } /** @@ -286,7 +294,7 @@ void VT_int_ClearLine(tVTerm *Term, int Row) { HEAP_VALIDATE(); - size_t height = Term->TextHeight * (Term->Flags & VT_FLAG_ALTBUF ? 1 : giVT_Scrollback + 1); + size_t height = VT_int_GetBufferRows(Term); tVT_Char *buffer = (Term->Flags & VT_FLAG_ALTBUF ? Term->AltBuf : Term->Text); ASSERTCR(Row, >=, 0, ); ASSERTCR(Row, <, height, ); @@ -306,7 +314,7 @@ void VT_int_ClearInLine(tVTerm *Term, int Row, int FirstCol, int LastCol) { HEAP_VALIDATE(); - size_t height = Term->TextHeight * (Term->Flags & VT_FLAG_ALTBUF ? 1 : giVT_Scrollback + 1); + size_t height = VT_int_GetBufferRows(Term); tVT_Char *buffer = (Term->Flags & VT_FLAG_ALTBUF ? Term->AltBuf : Term->Text); ASSERTCR(Row, >=, 0, ); ASSERTCR(Row, <, height, ); @@ -436,3 +444,13 @@ void VT_int_ToggleAltBuffer(tVTerm *Term, int Enabled) VT_int_UpdateScreen(Term, 1); } +tVT_Pos *VT_int_GetWritePosPtr(tVTerm *Term) +{ + return ((Term->Flags & VT_FLAG_ALTBUF) ? &Term->AltWritePos : &Term->WritePos); +} + +size_t VT_int_GetBufferRows(tVTerm *Term) +{ + return ((Term->Flags & VT_FLAG_ALTBUF) ? 1 : (giVT_Scrollback+1))*Term->TextHeight; +} +