From: John Hodge Date: Wed, 12 Feb 2014 14:23:07 +0000 (+0800) Subject: Kernel/VTerm - Replace offset WritePos with Row,Col pair X-Git-Url: https://git.ucc.asn.au/?p=tpg%2Facess2.git;a=commitdiff_plain;h=9659f4f4435c25edeafacece13450da80c9d5066 Kernel/VTerm - Replace offset WritePos with Row,Col pair --- diff --git a/KernelLand/Kernel/drv/vterm.c b/KernelLand/Kernel/drv/vterm.c index 1556aa81..9a88fa69 100644 --- a/KernelLand/Kernel/drv/vterm.c +++ b/KernelLand/Kernel/drv/vterm.c @@ -163,18 +163,12 @@ int VT_Install(char **Arguments) Log_Debug("VTerm", "Initialising nodes (and creating buffers)"); for( i = 0; i < NUM_VTS; i++ ) { - gVT_Terminals[i].Mode = TERM_MODE_TEXT; - gVT_Terminals[i].Flags = 0; // gVT_Terminals[i].Flags = VT_FLAG_HIDECSR; //HACK - Stop all those memcpy calls gVT_Terminals[i].CurColour = DEFAULT_COLOUR; - gVT_Terminals[i].WritePos = 0; - gVT_Terminals[i].AltWritePos = 0; - gVT_Terminals[i].ViewPos = 0; - gVT_Terminals[i].ScrollHeight = 0; + gVT_Terminals[i].Mode = PTYBUFFMT_TEXT; // Initialise VT_int_Resize( &gVT_Terminals[i], giVT_RealWidth, giVT_RealHeight ); - gVT_Terminals[i].Mode = PTYBUFFMT_TEXT; char name[] = {'v','t','0'+i,'\0'}; struct ptydims dims = { .W = giVT_RealWidth / giVT_CharWidth, diff --git a/KernelLand/Kernel/drv/vterm.h b/KernelLand/Kernel/drv/vterm.h index 4b783486..05aad87a 100644 --- a/KernelLand/Kernel/drv/vterm.h +++ b/KernelLand/Kernel/drv/vterm.h @@ -42,6 +42,12 @@ enum eVT_InModes { typedef struct sVTerm tVTerm; // === STRUCTURES === +typedef struct +{ + unsigned short Row; + unsigned short Col; +} tVT_Pos; + struct sVTerm { int Mode; //!< Current Mode (see ::eTplTerminal_Modes) @@ -56,15 +62,15 @@ struct sVTerm Uint32 CurColour; //!< Current Text Colour - size_t ViewPos; //!< View Buffer Offset (Text Only) - size_t WritePos; //!< Write Buffer Offset (Text Only) + size_t ViewTopRow; //!< View Buffer Offset (Text Only) + tVT_Pos WritePos; //!< Write Buffer Offset (Text Only) tVT_Char *Text; + tVT_Pos AltWritePos; //!< Alternate write position tVT_Char *AltBuf; //!< Alternate Screen Buffer - size_t AltWritePos; //!< Alternate write position short ScrollTop; //!< Top of scrolling region (smallest) short ScrollHeight; //!< Length of scrolling region - size_t SavedWritePos; //!< Saved cursor position (\e[s and \e[u) + tVT_Pos SavedWritePos; //!< Saved cursor position (\e[s and \e[u) char EscapeCodeCache[16]; size_t EscapeCodeLen; @@ -129,7 +135,7 @@ extern void VT_int_ClearInLine(tVTerm *Term, int Row, int FirstCol, int LastCol) extern void VT_int_Resize(tVTerm *Term, int NewWidth, int NewHeight); extern void VT_int_ToggleAltBuffer(tVTerm *Term, int Enabled); -extern size_t *VT_int_GetWritePosPtr(tVTerm *Term); +extern tVT_Pos *VT_int_GetWritePosPtr(tVTerm *Term); extern size_t VT_int_GetBufferRows(tVTerm *Term); #endif diff --git a/KernelLand/Kernel/drv/vterm_2d.c b/KernelLand/Kernel/drv/vterm_2d.c index 3994525f..4b750ab7 100644 --- a/KernelLand/Kernel/drv/vterm_2d.c +++ b/KernelLand/Kernel/drv/vterm_2d.c @@ -20,10 +20,9 @@ void VT_int_SetCursorPos(tVTerm *Term, int X, int Y) { if( Term->Mode == PTYBUFFMT_TEXT ) { - if(Term->Flags & VT_FLAG_ALTBUF) - Term->AltWritePos = X + Y * Term->TextWidth; - else - Term->WritePos = X + Y * Term->TextWidth + Term->ViewPos; + tVT_Pos *wrpos = VT_int_GetWritePosPtr(Term); + wrpos->Row = X; + wrpos->Col = Y + (Term->Flags & VT_FLAG_ALTBUF ? 0 : Term->ViewTopRow); VT_int_UpdateCursor(Term, 0); } else diff --git a/KernelLand/Kernel/drv/vterm_input.c b/KernelLand/Kernel/drv/vterm_input.c index 3e86087b..6c25cc81 100644 --- a/KernelLand/Kernel/drv/vterm_input.c +++ b/KernelLand/Kernel/drv/vterm_input.c @@ -101,16 +101,14 @@ void VT_KBCallBack(Uint32 Codepoint) case KEYSYM_PGUP: if( term->Flags & VT_FLAG_ALTBUF ) return ; - term->ViewPos = MAX( 0, term->ViewPos - term->Width ); + term->ViewTopRow = MAX(0, term->ViewTopRow - 1); VT_int_UpdateScreen(term, 1); return; case KEYSYM_PGDN: if( term->Flags & VT_FLAG_ALTBUF ) return ; - term->ViewPos = MIN( - term->ViewPos + term->Width, - term->Width * term->Height * giVT_Scrollback - ); + // Note the lack of giVT_Scrollback+1, view top can't go above size-onescreen + term->ViewTopRow = MIN(term->ViewTopRow + 1, term->Height * giVT_Scrollback); VT_int_UpdateScreen(term, 1); return; } diff --git a/KernelLand/Kernel/drv/vterm_output.c b/KernelLand/Kernel/drv/vterm_output.c index 9ee5f1ea..532d2686 100644 --- a/KernelLand/Kernel/drv/vterm_output.c +++ b/KernelLand/Kernel/drv/vterm_output.c @@ -96,8 +96,6 @@ void VT_int_UpdateCursor( tVTerm *Term, int bShow ) } else if( Term->Mode == TERM_MODE_TEXT ) { - int offset; - // if( !(Term->Flags & VT_FLAG_SHOWCSR) // && ( (Term->Flags & VT_FLAG_HIDECSR) || !Term->Node.ReadThreads) // ) @@ -108,13 +106,9 @@ void VT_int_UpdateCursor( tVTerm *Term, int bShow ) } else { - if(Term->Flags & VT_FLAG_ALTBUF) - offset = Term->AltWritePos; - else - offset = Term->WritePos - Term->ViewPos; - - csr_pos.x = offset % Term->TextWidth; - csr_pos.y = offset / Term->TextWidth; + const tVT_Pos *wrpos = VT_int_GetWritePosPtr(Term); + csr_pos.x = wrpos->Col; + csr_pos.y = wrpos->Row - (Term->Flags & VT_FLAG_ALTBUF ? 0 : Term->ViewTopRow); if( 0 > csr_pos.y || csr_pos.y >= Term->TextHeight ) csr_pos.y = -1, csr_pos.x = -1; } @@ -139,8 +133,8 @@ void VT_int_UpdateScreen( tVTerm *Term, int UpdateAll ) switch( Term->Mode ) { case TERM_MODE_TEXT: { - size_t view_pos = (Term->Flags & VT_FLAG_ALTBUF) ? 0 : Term->ViewPos; - size_t write_pos = (Term->Flags & VT_FLAG_ALTBUF) ? Term->AltWritePos : Term->WritePos; + size_t view_pos = (Term->Flags & VT_FLAG_ALTBUF) ? 0 : Term->ViewTopRow*Term->TextWidth; + const tVT_Pos *wrpos = VT_int_GetWritePosPtr(Term); const tVT_Char *buffer = (Term->Flags & VT_FLAG_ALTBUF) ? Term->AltBuf : Term->Text; // Re copy the entire screen? if(UpdateAll) { @@ -153,7 +147,7 @@ void VT_int_UpdateScreen( tVTerm *Term, int UpdateAll ) } // Only copy the current line else { - int ofs = write_pos - write_pos % Term->TextWidth; + size_t ofs = wrpos->Row * Term->TextWidth; VFS_WriteAt( giVT_OutputDevHandle, (ofs - view_pos)*sizeof(tVT_Char), diff --git a/KernelLand/Kernel/drv/vterm_termbuf.c b/KernelLand/Kernel/drv/vterm_termbuf.c index d4ea9a41..4902cd8a 100644 --- a/KernelLand/Kernel/drv/vterm_termbuf.c +++ b/KernelLand/Kernel/drv/vterm_termbuf.c @@ -5,7 +5,7 @@ * drv/vterm_termbuf.c * - Virtual Terminal - Terminal buffer manipulation */ -#define DEBUG 0 +#define DEBUG 1 #define DEBUG_CHECKHEAP 0 #include "vterm.h" @@ -65,60 +65,71 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch) HEAP_VALIDATE(); - size_t limit = VT_int_GetBufferRows(Term) * Term->TextWidth; - size_t write_pos = *VT_int_GetWritePosPtr(Term); + 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); - ASSERTC(write_pos, >=, 0); + // 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; + } // Scroll entire buffer (about to write outside limit) - if( write_pos >= limit ) + if( wrpos->Row >= maxrows ) { - ASSERTC(write_pos, <, limit + Term->TextWidth); + ASSERTC(wrpos->Row, <, maxrows + 1); VT_int_ScrollText(Term, 1); - write_pos -= Term->TextWidth; + wrpos->Row --; } // Bring written cell into view if( !(Term->Flags & VT_FLAG_ALTBUF) ) { - size_t onescreen = Term->TextWidth*Term->TextHeight; - if( write_pos >= Term->ViewPos + onescreen ) + if( wrpos->Row >= Term->ViewTopRow + Term->TextHeight ) { - size_t new_pos = write_pos - (write_pos % Term->TextWidth) - onescreen + Term->TextWidth; - size_t count = (new_pos - Term->ViewPos) / Term->TextWidth; + 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->TextWidth); - Term->ViewPos = new_pos; + //Debug("VT_int_PutChar: VScroll down to %i", new_pos); + Term->ViewTopRow = new_pos; } - else if( write_pos < Term->ViewPos ) + else if( wrpos->Row < Term->ViewTopRow ) { - size_t new_pos = write_pos - (write_pos % Term->TextWidth); - size_t count = (Term->ViewPos - new_pos) / Term->TextWidth; + 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->TextWidth); - Term->ViewPos = new_pos; + //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': VT_int_UpdateScreen( Term, 0 ); // Update the line before newlining - write_pos += Term->TextWidth; - // TODO: Scroll display down if needed + 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; @@ -147,6 +158,7 @@ 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: @@ -156,11 +168,11 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch) if( (write_pos + 1) % Term->TextWidth == 0 ) VT_int_UpdateScreen( Term, 0 ); write_pos ++; + wrpos->Col ++; break; } ASSERTC(write_pos, <=, limit); - *VT_int_GetWritePosPtr(Term) = write_pos; HEAP_VALIDATE(); @@ -176,7 +188,7 @@ void VT_int_ScrollText(tVTerm *Term, int Count) // Get buffer pointer and attributes size_t height = VT_int_GetBufferRows(Term); - size_t *write_pos_ptr = VT_int_GetWritePosPtr(Term); + tVT_Pos *wrpos = VT_int_GetWritePosPtr(Term); if( Term->Flags & VT_FLAG_ALTBUF ) { @@ -191,7 +203,7 @@ void VT_int_ScrollText(tVTerm *Term, int Count) 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 ) @@ -217,13 +229,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 @@ -249,16 +261,17 @@ 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(); } @@ -422,7 +435,7 @@ void VT_int_ToggleAltBuffer(tVTerm *Term, int Enabled) VT_int_UpdateScreen(Term, 1); } -size_t *VT_int_GetWritePosPtr(tVTerm *Term) +tVT_Pos *VT_int_GetWritePosPtr(tVTerm *Term) { return ((Term->Flags & VT_FLAG_ALTBUF) ? &Term->AltWritePos : &Term->WritePos); } diff --git a/KernelLand/Kernel/drv/vterm_vt100.c b/KernelLand/Kernel/drv/vterm_vt100.c index 34505363..b5d60a94 100644 --- a/KernelLand/Kernel/drv/vterm_vt100.c +++ b/KernelLand/Kernel/drv/vterm_vt100.c @@ -5,7 +5,7 @@ * drv/vterm_vt100.c * - Virtual Terminal - VT100 (Kinda) Emulation */ -#define DEBUG 0 +#define DEBUG 1 #include "vterm.h" #define sTerminal sVTerm @@ -47,12 +47,12 @@ void Display_ScrollDown(tTerminal *Term, int CountDown) VT_int_ScrollText(Term, CountDown); else { - if(Term->ViewPos/Term->TextWidth + CountDown < 0) + if(Term->ViewTopRow + CountDown < 0) return ; - if(Term->ViewPos/Term->TextWidth + CountDown > Term->TextHeight * (giVT_Scrollback + 1)) + if(Term->ViewTopRow + CountDown > Term->TextHeight * (giVT_Scrollback + 1)) return ; - Term->ViewPos += Term->TextWidth * CountDown; + Term->ViewTopRow += CountDown; } } void Display_SetCursor(tTerminal *Term, int Row, int Col) @@ -64,12 +64,13 @@ void Display_SetCursor(tTerminal *Term, int Row, int Col) ASSERTCR( Row, <, maxrows, ); ASSERTCR( Col, >=, 0, ); ASSERTCR( Col, <, Term->TextWidth, ); - *VT_int_GetWritePosPtr(Term) = Row*Term->TextWidth + Col; + VT_int_GetWritePosPtr(Term)->Row = Row; + VT_int_GetWritePosPtr(Term)->Col = Col; } void Display_MoveCursor(tTerminal *Term, int RelRow, int RelCol) { LOG("(R+%i,C+%i)", RelRow, RelCol); - size_t *wrpos = VT_int_GetWritePosPtr(Term); + tVT_Pos *wrpos = VT_int_GetWritePosPtr(Term); // TODO: Support scrolling if cursor goes offscreen // if( bScrollIfNeeded ) @@ -82,21 +83,21 @@ void Display_MoveCursor(tTerminal *Term, int RelRow, int RelCol) // if( RelCol < 0 ) { - int max = *wrpos % Term->TextWidth; + int max = wrpos->Col; if( RelCol < -max ) RelCol = -max; } else { - size_t max = Term->TextWidth - (*wrpos % Term->TextWidth) - 1; + size_t max = Term->TextWidth - wrpos->Col - 1; if(RelCol > max) RelCol = max; } - *wrpos += RelCol; + wrpos->Col += RelCol; } if( RelRow != 0 ) { - int currow = *wrpos / Term->TextWidth; + int currow = wrpos->Row; int maxrows = VT_int_GetBufferRows(Term); if( RelRow < 0 ) { @@ -108,9 +109,9 @@ void Display_MoveCursor(tTerminal *Term, int RelRow, int RelCol) if( currow + RelRow > maxrows-1 ) RelRow = maxrows-1 - currow; } - *wrpos += RelRow*Term->TextWidth; + wrpos->Row += RelRow; } - LOG("=(R%i,C%i)", *wrpos / Term->TextWidth, *wrpos % Term->TextWidth); + LOG("=(R%i,C%i)", wrpos->Row, wrpos->Col); } void Display_SaveCursor(tTerminal *Term) { @@ -119,33 +120,35 @@ void Display_SaveCursor(tTerminal *Term) } void Display_RestoreCursor(tTerminal *Term) { - size_t max = VT_int_GetBufferRows(Term) * Term->TextWidth; - size_t *wrpos = VT_int_GetWritePosPtr(Term); - *wrpos = MIN(Term->SavedWritePos, max-1); - LOG("Restored %i", *wrpos); + size_t maxrow = VT_int_GetBufferRows(Term); + tVT_Pos *wrpos = VT_int_GetWritePosPtr(Term); + *wrpos = Term->SavedWritePos; + if(wrpos->Row >= maxrow) + wrpos->Row = maxrow-1; + if(wrpos->Col >= Term->TextWidth ) + wrpos->Col = Term->TextWidth-1; + LOG("Restored (R%i,C%i)", wrpos->Row, wrpos->Col); } // 0: All, 1: Forward, -1: Reverse void Display_ClearLine(tTerminal *Term, int Dir) { - const size_t wrpos = *VT_int_GetWritePosPtr(Term); - const int row = wrpos / Term->TextWidth; - const int col = wrpos % Term->TextWidth; + const tVT_Pos *wrpos = VT_int_GetWritePosPtr(Term); LOG("(Dir=%i)", Dir); // Erase all if( Dir == 0 ) { - VT_int_ClearLine(Term, row); + VT_int_ClearLine(Term, wrpos->Row); VT_int_UpdateScreen(Term, 0); } // Erase to right else if( Dir == 1 ) { - VT_int_ClearInLine(Term, row, col, Term->TextWidth); + VT_int_ClearInLine(Term, wrpos->Row, wrpos->Col, Term->TextWidth); VT_int_UpdateScreen(Term, 0); } // Erase to left else if( Dir == -1 ) { - VT_int_ClearInLine(Term, row, 0, col); + VT_int_ClearInLine(Term, wrpos->Row, 0, wrpos->Col); VT_int_UpdateScreen(Term, 0); } else { @@ -157,30 +160,31 @@ void Display_ClearLine(tTerminal *Term, int Dir) void Display_ClearLines(tTerminal *Term, int Dir) { LOG("(Dir=%i)", Dir); - size_t *wrpos = VT_int_GetWritePosPtr(Term); + tVT_Pos *wrpos = VT_int_GetWritePosPtr(Term); size_t height = VT_int_GetBufferRows(Term); // All if( Dir == 0 ) { if( !(Term->Flags & VT_FLAG_ALTBUF) ) { - Term->ViewPos = 0; + Term->ViewTopRow = 0; } int count = height; while( count -- ) VT_int_ClearLine(Term, count); - *wrpos = 0; + wrpos->Col = 0; + wrpos->Row = 0; VT_int_UpdateScreen(Term, 1); } // Downwards else if( Dir == 1 ) { - for( int row = *wrpos / Term->TextWidth; row < height; row ++ ) + for( int row = wrpos->Row; row < height; row ++ ) VT_int_ClearLine(Term, row); VT_int_UpdateScreen(Term, 1); } // Upwards else if( Dir == -1 ) { - for( int row = 0; row < *wrpos / Term->TextWidth; row ++ ) + for( int row = 0; row < wrpos->Row; row ++ ) VT_int_ClearLine(Term, row); VT_int_UpdateScreen(Term, 1); }