Kernel/VTerm - Replace offset WritePos with Row,Col pair
authorJohn Hodge <[email protected]>
Wed, 12 Feb 2014 14:23:07 +0000 (22:23 +0800)
committerJohn Hodge <[email protected]>
Wed, 12 Feb 2014 14:23:07 +0000 (22:23 +0800)
KernelLand/Kernel/drv/vterm.c
KernelLand/Kernel/drv/vterm.h
KernelLand/Kernel/drv/vterm_2d.c
KernelLand/Kernel/drv/vterm_input.c
KernelLand/Kernel/drv/vterm_output.c
KernelLand/Kernel/drv/vterm_termbuf.c
KernelLand/Kernel/drv/vterm_vt100.c

index 1556aa8..9a88fa6 100644 (file)
@@ -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,
index 4b78348..05aad87 100644 (file)
@@ -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
index 3994525..4b750ab 100644 (file)
@@ -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
index 3e86087..6c25cc8 100644 (file)
@@ -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;
                }
index 9ee5f1e..532d268 100644 (file)
@@ -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),
index d4ea9a4..4902cd8 100644 (file)
@@ -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);
 }
index 3450536..b5d60a9 100644 (file)
@@ -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);
        }

UCC git Repository :: git.ucc.asn.au