Kernel - Attempting to fix scroll redraw issue
[tpg/acess2.git] / Kernel / drv / vterm.c
index bead23c..1bf3dd6 100644 (file)
@@ -11,8 +11,6 @@
 #include <errno.h>
 #include <semaphore.h>
 
-#define        USE_CTRL_ALT    1
-
 // === CONSTANTS ===
 #define VERSION        ((0<<8)|(50))
 
@@ -21,6 +19,7 @@
 #define MAX_INPUT_CHARS8       (MAX_INPUT_CHARS32*4)
 //#define DEFAULT_OUTPUT       "BochsGA"
 #define DEFAULT_OUTPUT "Vesa"
+#define FALLBACK_OUTPUT        "x86_VGAText"
 #define DEFAULT_INPUT  "PS2Keyboard"
 #define        DEFAULT_WIDTH   640
 #define        DEFAULT_HEIGHT  480
@@ -29,6 +28,7 @@
 
 #define        VT_FLAG_HIDECSR 0x01
 #define        VT_FLAG_ALTBUF  0x02    //!< Alternate screen buffer
+#define VT_FLAG_RAWIN  0x04    //!< Don't handle ^Z/^C/^V
 #define        VT_FLAG_HASFB   0x10    //!< Set if the VTerm has requested the Framebuffer
 
 enum eVT_InModes {
@@ -109,7 +109,7 @@ const Uint16        caVT100Colours[] = {
        };
 
 // === GLOBALS ===
-MODULE_DEFINE(0, VERSION, VTerm, VT_Install, NULL, DEFAULT_OUTPUT, DEFAULT_INPUT, NULL);
+MODULE_DEFINE(0, VERSION, VTerm, VT_Install, NULL, FALLBACK_OUTPUT, DEFAULT_INPUT, NULL);
 tDevFS_Driver  gVT_DrvInfo = {
        NULL, "VTerm",
        {
@@ -169,11 +169,11 @@ int VT_Install(char **Arguments)
                        Log_Debug("VTerm", "Argument '%s'", arg);
                        
                        if( strcmp(opt, "Video") == 0 ) {
-                               if( !gsVT_OutputDevice && Modules_InitialiseBuiltin( val ) == 0 )
+                               if( !gsVT_OutputDevice )
                                        gsVT_OutputDevice = strdup(val);
                        }
                        else if( strcmp(opt, "Input") == 0 ) {
-                               if( !gsVT_InputDevice && Modules_InitialiseBuiltin( val ) == 0 )
+                               if( !gsVT_InputDevice )
                                        gsVT_InputDevice = strdup(val);
                        }
                        else if( strcmp(opt, "Width") == 0 ) {
@@ -189,16 +189,21 @@ int VT_Install(char **Arguments)
        }
        
        // Apply Defaults
-       if(!gsVT_OutputDevice)  gsVT_OutputDevice = strdup(DEFAULT_OUTPUT);
-       if(!gsVT_InputDevice)   gsVT_InputDevice = strdup(DEFAULT_INPUT);
+       if(!gsVT_OutputDevice)  gsVT_OutputDevice = (char*)DEFAULT_OUTPUT;
+       else if( Module_EnsureLoaded( gsVT_OutputDevice ) )     gsVT_OutputDevice = (char*)DEFAULT_OUTPUT;
+       if( Module_EnsureLoaded( gsVT_OutputDevice ) )  gsVT_OutputDevice = (char*)FALLBACK_OUTPUT;
+       
+       if(!gsVT_InputDevice)   gsVT_InputDevice = (char*)DEFAULT_INPUT;
+       else if( Module_EnsureLoaded( gsVT_InputDevice ) )      gsVT_InputDevice = (char*)DEFAULT_INPUT;
        
-       // Create paths
+       // Create device paths
        {
                char    *tmp;
                tmp = malloc( 9 + strlen(gsVT_OutputDevice) + 1 );
                strcpy(tmp, "/Devices/");
                strcpy(&tmp[9], gsVT_OutputDevice);
                gsVT_OutputDevice = tmp;
+
                tmp = malloc( 9 + strlen(gsVT_InputDevice) + 1 );
                strcpy(tmp, "/Devices/");
                strcpy(&tmp[9], gsVT_InputDevice);
@@ -245,7 +250,6 @@ int VT_Install(char **Arguments)
        // Set kernel output to VT0
        Debug_SetKTerminal("/Devices/VTerm/0");
        
-       Log_Log("VTerm", "Returning %i", MODULE_ERR_OK);
        return MODULE_ERR_OK;
 }
 
@@ -319,12 +323,15 @@ void VT_SetResolution(int Width, int Height)
                // Resize the text terminals
                giVT_RealWidth = mode.width;
                giVT_RealHeight = mode.height;
+               Log_Debug("VTerm", "Resizing terminals to %ix%i",
+                       giVT_RealWidth/giVT_CharWidth, giVT_RealHeight/giVT_CharHeight);
                for( i = 0; i < NUM_VTS; i ++ )
                {
                        if( gVT_Terminals[i].Mode != TERM_MODE_TEXT )   continue;
                        
                        gVT_Terminals[i].TextWidth = giVT_RealWidth/giVT_CharWidth;
                        gVT_Terminals[i].TextHeight = giVT_RealHeight/giVT_CharHeight;
+                       gVT_Terminals[i].ScrollHeight = gVT_Terminals[i].TextHeight;
                        
                        gVT_Terminals[i].Text = realloc(
                                gVT_Terminals[i].Text,
@@ -426,7 +433,6 @@ int VT_Root_IOCtl(tVFS_Node *Node, int Id, void *Data)
 }
 
 /**
- * \fn Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
  * \brief Read from a virtual terminal
  */
 Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
@@ -465,7 +471,7 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        // Other - UCS-4
        default:
                VFS_SelectNode(Node, VFS_SELECT_READ, NULL, "VT_Read (UCS-4)");
-                       
+               
                avail = term->InputWrite - term->InputRead;
                if(avail < 0)
                        avail += MAX_INPUT_CHARS32;
@@ -752,30 +758,20 @@ void VT_KBCallBack(Uint32 Codepoint)
                Codepoint &= 0x7FFFFFFF;
                switch(Codepoint)
                {
-               #if !USE_CTRL_ALT
-               case KEY_RSHIFT:        gbVT_CtrlDown = 0;      break;
-               case KEY_LSHIFT:        gbVT_AltDown = 0;       break;
-               #else
                case KEY_LALT:  gbVT_AltDown &= ~1;     break;
                case KEY_RALT:  gbVT_AltDown &= ~2;     break;
                case KEY_LCTRL: gbVT_CtrlDown &= ~1;    break;
                case KEY_RCTRL: gbVT_CtrlDown &= ~2;    break;
-               #endif
                }
                return;
        }
        
        switch(Codepoint)
        {
-       #if !USE_CTRL_ALT       // HACK: Use both shifts instead of Ctrl-Alt
-       case KEY_RSHIFT:        gbVT_CtrlDown = 1;      break;
-       case KEY_LSHIFT:        gbVT_AltDown = 1;       break;
-       #else
        case KEY_LALT:  gbVT_AltDown |= 1;      break;
        case KEY_RALT:  gbVT_AltDown |= 2;      break;
        case KEY_LCTRL: gbVT_CtrlDown |= 1;     break;
        case KEY_RCTRL: gbVT_CtrlDown |= 2;     break;
-       #endif
        
        default:
                if(!gbVT_AltDown || !gbVT_CtrlDown)
@@ -865,6 +861,19 @@ void VT_KBCallBack(Uint32 Codepoint)
                        // Unprintable / Don't Pass
                        return;
                }
+
+#if 0
+               // Handle meta characters
+               if( !(term->Flags & VT_FLAG_RAWIN) )
+               {
+                       switch(buf[0])
+                       {
+                       case '\3':      // ^C
+                               
+                               break;
+                       }
+               }
+#endif
                
                // Write
                if( MAX_INPUT_CHARS8 - term->InputWrite >= len )
@@ -1047,6 +1056,57 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer)
                                                break;
                                        }
                                        break;
+                               
+                               // Erase in line
+                               case 'K':
+                                       switch(args[0])
+                                       {
+                                       case 0: // Erase to right
+                                               if( Term->Flags & VT_FLAG_ALTBUF )
+                                               {
+                                                        int    i, max;
+                                                       max = Term->Width - Term->AltWritePos % Term->Width;
+                                                       for( i = 0; i < max; i ++ )
+                                                               Term->AltBuf[Term->AltWritePos+i].Ch = 0;
+                                               }
+                                               else
+                                               {
+                                                        int    i, max;
+                                                       max = Term->Width - Term->WritePos % Term->Width;
+                                                       for( i = 0; i < max; i ++ )
+                                                               Term->Text[Term->WritePos+i].Ch = 0;
+                                               }
+                                               VT_int_UpdateScreen(Term, 0);
+                                               break;
+                                       case 1: // Erase to left
+                                               if( Term->Flags & VT_FLAG_ALTBUF )
+                                               {
+                                                        int    i = Term->AltWritePos % Term->Width;
+                                                       while( i -- )
+                                                               Term->AltBuf[Term->AltWritePos++].Ch = 0;
+                                               }
+                                               else
+                                               {
+                                                        int    i = Term->WritePos % Term->Width;
+                                                       while( i -- )
+                                                               Term->Text[Term->WritePos++].Ch = 0;
+                                               }
+                                               VT_int_UpdateScreen(Term, 0);
+                                               break;
+                                       case 2: // Erase all
+                                               if( Term->Flags & VT_FLAG_ALTBUF )
+                                               {
+                                                       VT_int_ClearLine(Term, Term->AltWritePos / Term->Width);
+                                               }
+                                               else
+                                               {
+                                                       VT_int_ClearLine(Term, Term->WritePos / Term->Width);
+                                               }
+                                               VT_int_UpdateScreen(Term, 0);
+                                               break;
+                                       }
+                                       break;
+                               
                                // Set cursor position
                                case 'H':
                                        if( Term->Flags & VT_FLAG_ALTBUF )
@@ -1196,13 +1256,15 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch)
                write_pos -= write_pos % Term->TextWidth;
                break;
        
-       case '\t':
+       case '\t': { int tmp = write_pos / Term->TextWidth;
+               write_pos %= Term->TextWidth;
                do {
                        buffer[ write_pos ].Ch = '\0';
                        buffer[ write_pos ].Colour = Term->CurColour;
                        write_pos ++;
                } while(write_pos & 7);
-               break;
+               write_pos += tmp * Term->TextWidth;
+               break; }
        
        case '\b':
                // Backspace is invalid at Offset 0
@@ -1311,6 +1373,7 @@ void VT_int_ScrollText(tVTerm *Term, int Count)
        {
                 int    base;
                if(Count > Term->ScrollHeight)  Count = Term->ScrollHeight;
+//             Debug("Scroll: Count = %i", Count);
                base = Term->TextWidth*(Term->ScrollTop + Term->ScrollHeight - Count);
                len = Term->TextWidth*(Term->ScrollHeight - Count);
                
@@ -1323,8 +1386,8 @@ void VT_int_ScrollText(tVTerm *Term, int Count)
                // Clear last rows
                for( i = 0; i < Term->TextWidth*Count; i ++ )
                {
-                       Term->AltBuf[ base + i ].Ch = 0;
-                       Term->AltBuf[ base + i ].Colour = Term->CurColour;
+                       buf[ base + i ].Ch = 0;
+                       buf[ base + i ].Colour = Term->CurColour;
                }
                
                // Update Screen
@@ -1333,7 +1396,6 @@ void VT_int_ScrollText(tVTerm *Term, int Count)
                        Term->AltWritePos = Term->TextWidth*(Term->ScrollTop + Term->ScrollHeight - Count);
                else
                        Term->WritePos = Term->ViewPos + Term->TextWidth*(Term->ScrollTop + Term->ScrollHeight - Count);
-//             Log_Debug("VTerm", "Term->WritePos = %i/%i = %i", Term->WritePos, Term->TextWidth, Term->WritePos/Term->TextWidth);
                for( i = 0; i < Count; i ++ )
                {
                        VT_int_UpdateScreen( Term, 0 );
@@ -1359,8 +1421,8 @@ void VT_int_ScrollText(tVTerm *Term, int Count)
                // Clear preceding rows
                for( i = 0; i < Term->TextWidth*Count; i ++ )
                {
-                       Term->AltBuf[ i ].Ch = 0;
-                       Term->AltBuf[ i ].Colour = Term->CurColour;
+                       buf[ i ].Ch = 0;
+                       buf[ i ].Colour = Term->CurColour;
                }
                
                VT_int_ScrollFramebuffer( Term, -Count );
@@ -1411,6 +1473,7 @@ void VT_int_ScrollFramebuffer( tVTerm *Term, int Count )
        // BLIT to 0,0 from 0,giVT_CharHeight
        buf.Op = VIDEO_2DOP_BLIT;
        buf.SrcX = 0;   buf.DstX = 0;
+       // TODO: Don't assume character dimensions
        buf.W = Term->TextWidth * giVT_CharWidth;
        if( Count > 0 )
        {
@@ -1582,6 +1645,7 @@ void VT_int_ToggleAltBuffer(tVTerm *Term, int Enabled)
                Term->Flags |= VT_FLAG_ALTBUF;
        else
                Term->Flags &= ~VT_FLAG_ALTBUF;
+       VT_int_UpdateScreen(Term, 1);
 }
 
 // ---

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