VT100 - Replace global buffer with per-terminal, further implementation of escape...
authorJohn Hodge <[email protected]>
Sun, 9 Feb 2014 14:32:07 +0000 (22:32 +0800)
committerJohn Hodge <[email protected]>
Sun, 9 Feb 2014 14:32:07 +0000 (22:32 +0800)
KernelLand/Kernel/drv/vterm_vt100.c
Usermode/Applications/gui_terminal_src/display.c
Usermode/Applications/gui_terminal_src/include/display.h
Usermode/Applications/gui_terminal_src/vt100.c

index fb5e973..ccb0c52 100644 (file)
 #include "../../../Usermode/Applications/gui_terminal_src/vt100.c"
 
 void *Display_GetTermState(tTerminal *Term) {
-       return Term->VT100Info;;
+       return Term->VT100Info;
 }
 void Display_SetTermState(tTerminal *Term, void *State) {
        Term->VT100Info = State;
 }
 
+void Display_SendInput(tTerminal *Term, const char *String)
+{
+       PTY_SendInput(Term->PTY, String, strlen(String));
+}
+
 void Display_AddText(tTerminal *Term, size_t Length, const char *UTF8Text)
 {
        LOG("'%*C'", Length, UTF8Text);
@@ -66,6 +71,12 @@ void Display_MoveCursor(tTerminal *Term, int RelRow, int RelCol)
        LOG("(R+%i,C+%i)", RelRow, RelCol);
        int     *wrpos = (Term->Flags & VT_FLAG_ALTBUF ? &Term->AltWritePos : &Term->WritePos);
 
+       // TODO: Support scrolling if cursor goes offscreen
+       // if( bScrollIfNeeded )
+       //      Display_ScrollDown(extra);
+       // else
+       //      clip
+
        if( RelCol != 0 )
        {
                // 
@@ -150,18 +161,15 @@ void Display_ClearLines(tTerminal *Term, int Dir)
 {
        LOG("(Dir=%i)", Dir);   
         int    *wrpos = (Term->Flags & VT_FLAG_ALTBUF ? &Term->AltWritePos : &Term->WritePos);
+        int    height = Term->TextHeight * (Term->Flags & VT_FLAG_ALTBUF ? 1 : giVT_Scrollback + 1);
        
        // All
        if( Dir == 0 ) {
-               int count;
                
-               if( Term->Flags & VT_FLAG_ALTBUF ) {
-                       count = Term->TextHeight;
-               }
-               else {
-                       count = Term->TextHeight * (giVT_Scrollback + 1);
+               if( !(Term->Flags & VT_FLAG_ALTBUF) ) {
                        Term->ViewPos = 0;
                }
+               int count = height;
                while( count -- )
                        VT_int_ClearLine(Term, count);
                *wrpos = 0;
@@ -169,11 +177,15 @@ void Display_ClearLines(tTerminal *Term, int Dir)
        }
        // Downwards
        else if( Dir == 1 ) {
-               Log_Warning("VTerm", "TODO: ClearLines Down");
+               for( int row = *wrpos / Term->TextWidth; row < height; row ++ )
+                       VT_int_ClearLine(Term, row);
+               VT_int_UpdateScreen(Term, 1);
        }
        // Upwards
        else if( Dir == -1 ) {
-               Log_Warning("VTerm", "TODO: ClearLines Up");
+               for( int row = 0; row < *wrpos / Term->TextWidth; row ++ )
+                       VT_int_ClearLine(Term, row);
+               VT_int_UpdateScreen(Term, 1);
        }
        else {
                // ERROR!
index 5e3410b..7c60c9f 100644 (file)
@@ -30,6 +30,7 @@ static inline int MAX(int a, int b) { return (a > b ? a : b); }
 
 // === EXTERN ==
 extern tHWND   gMainWindow;
+extern int     giPTYHandle;
 
 typedef struct sLine   tLine;
 
@@ -106,6 +107,11 @@ void Display_SetTermState(tTerminal *Term, void *State) {
        Term->TermState = State;
 }
 
+void Display_SendInput(tTerminal *Term, const char *String)
+{
+       _SysWrite(giPTYHandle, String, strlen(String));
+}
+
 // Return the byte length of a single on-screen character
 size_t _GetCharLength(size_t AvailLength, const char *Text, uint32_t *BaseCodepoint)
 {
index 59abfba..51eea79 100644 (file)
@@ -20,6 +20,8 @@ extern tTerminal      *Display_Init(int Cols, int Lines, int ExtraScrollbackLines);
 extern void    *Display_GetTermState(tTerminal *Term);
 extern void    Display_SetTermState(tTerminal *Term, void *State);
 
+extern void    Display_SendInput(tTerminal *Term, const char *String);
+
 extern void    Display_AddText(tTerminal *Term, size_t Length, const char *UTF8Text);
 extern void    Display_Newline(tTerminal *Term, bool bCarriageReturn);
 extern void    Display_SetScrollArea(tTerminal *Term, int Start, int Count);   // Only valid in AltBuffer
index dc1902f..840f2d9 100644 (file)
@@ -31,10 +31,14 @@ enum eStringType {
 #define FLAG_BOLD      0x01
 #define FLAG_REVERSE   0x02
 
+#define        MAX_VT100_ESCAPE_LEN    32
 typedef struct {
        uint32_t        Flags;
        int     CurFG, CurBG;
-       
+
+       char    cache[MAX_VT100_ESCAPE_LEN];
+        int    cache_len;      
+
        enum eExcapeMode        Mode;
        
        enum eStringType        StringType;
@@ -75,9 +79,6 @@ int _locate_eos(size_t Len, const char *Buf)
 
 int Term_HandleVT100(tTerminal *Term, int Len, const char *Buf)
 {
-       #define MAX_VT100_ESCAPE_LEN    16
-       static char     inc_buf[MAX_VT100_ESCAPE_LEN];
-       static int      inc_len = 0;
        tVT100State     *st = Display_GetTermState(Term);
        
        if( st == NULL ) {
@@ -133,42 +134,45 @@ int Term_HandleVT100(tTerminal *Term, int Len, const char *Buf)
                // fall through
        }
 
-       if( inc_len > 0 || *Buf == '\x1b' )
+       if( st->cache_len > 0   || *Buf == '\x1b' )
        {
                // Handle VT100 (like) escape sequence
-                int    new_bytes = min(MAX_VT100_ESCAPE_LEN - inc_len, Len);
+                int    new_bytes = min(MAX_VT100_ESCAPE_LEN - st->cache_len, Len);
                 int    ret = 0;
-                int    old_inc_len = inc_len;
-               memcpy(inc_buf + inc_len, Buf, new_bytes);
+                int    old_inc_len = st->cache_len;
+               
+               memcpy(st->cache + st->cache_len, Buf, new_bytes);
 
                if( new_bytes == 0 ) {
                        _SysDebug("Term_HandleVT100: Hit max? (Len=%i) Flushing cache", Len);
-                       inc_len = 0;
+                       st->cache_len = 0;
                        return 0;
                }
 
-               inc_len += new_bytes;
-               //_SysDebug("inc_buf = %i '%.*s'", inc_len, inc_len, inc_buf);
+               st->cache_len += new_bytes;
+               assert(st->cache_len > old_inc_len);
 
-               if( inc_len <= 1 )
+               if( st->cache_len <= 1 )
                        return 1;       // Skip 1 character (the '\x1b')
 
-               ret = Term_HandleVT100_Short(Term, inc_len, inc_buf);
+               ret = Term_HandleVT100_Short(Term, st->cache_len, st->cache);
 
                if( ret != 0 ) {
-                       inc_len = 0;
                        // Check that we actually used the new data (as should have happened)
                        if( ret <= old_inc_len ) {
-                               _SysDebug("Term_HandleVT100: ret(%i) <= old_inc_len(%i) '%.*s'\n",
-                                       ret, old_inc_len, inc_len, inc_buf);
+                               _SysDebug("Term_HandleVT100: ret(%i) <= old_inc_len(%i), inc_len=%i, '%*C'",
+                                       ret, old_inc_len, st->cache_len, st->cache_len, st->cache);
                                assert(ret > old_inc_len);
                        }
+                       st->cache_len = 0;
                        //_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
+               else {
                        ret = new_bytes;
+                       _SysDebug("Term_HandleVT100: Caching %i bytes '%*C'", ret, ret, st->cache);
+               }
                return ret;
        }
 
@@ -183,6 +187,7 @@ int Term_HandleVT100(tTerminal *Term, int Len, const char *Buf)
        case '\t':
                // TODO: tab (get current cursor pos, space until multiple of 8)
                _SysDebug("TODO: VT100 Support \\t tab");
+               Display_AddText(Term, 1, "\t"); // pass the buck for now
                return 1;
        case '\n':
                // TODO: Support disabling CR after NL
@@ -237,6 +242,21 @@ int Term_HandleVT100_Short(tTerminal *Term, int Len, const char *Buf)
                if( tmp == 0 )
                        return 0;
                return tmp + 2;
+       
+       case '#':
+               if( Len == 2 )
+                       return 0;
+               switch(Buf[2])
+               {
+               case 8:
+                       _SysDebug("TODO \\e#%c - Fill screen with 'E'", Buf[2]);
+                       break;
+               default:
+                       _SysDebug("Unknown \\e#%c", Buf[2]);
+                       break;
+               }
+               return 3;
+               
        case '=':
                _SysDebug("TODO: \\e= Application Keypad");
                return 2;
@@ -263,16 +283,27 @@ int Term_HandleVT100_Short(tTerminal *Term, int Len, const char *Buf)
                        break;
                }
                return 3;
-       // xterm C1 \eD and \eM are 'Index' and 'Reverse Index'
-       // - Aparently scroll?
-       //case 'D':
-       //      Display_ScrollDown(Term, 1);
-       //      ret = 2;
-       //      break;
-       //case 'M':
-       //      Display_ScrollDown(Term, -1);
-       //      ret = 2;
-       //      break;
+       case '7':
+               // Save cursor
+               Display_SaveCursor(Term);
+               return 2;
+       case '8':
+               // Restore cursor
+               Display_RestoreCursor(Term);
+               return 2;
+       case 'D':
+               // Cursor down, if at bottom scroll
+               Display_MoveCursor(Term, 1, 0);
+               // TODO: Scroll if at bottom (impl in _MoveCursor)
+               return 2;
+       case 'E':
+               Display_MoveCursor(Term, 1, INT_MIN);
+               // TODO: Scroll if at bottom (impl in _MoveCursor)
+               return 2;
+       case 'M':
+               // Cursor up, scroll if at top
+               Display_MoveCursor(Term, -1, 0);
+               return 2;
        default:
                _SysDebug("Unknown VT100 \\e%c", Buf[1]);
                return 2;
@@ -290,13 +321,16 @@ int Term_HandleVT100_Long(tTerminal *Term, int Len, const char *Buffer)
        // Get Arguments
        if(j == Len)    return 0;
        c = Buffer[j++];
-       if(c == '?') {
+       if(c == '?')
+       {
                bQuestionMark = 1;
                if(j == Len)    return 0;
                c = Buffer[j++];
        }
-       if( '0' <= c && c <= '9' )
+       if( ('0' <= c && c <= '9') || c == ';' )
        {
+               if(c == ';')
+                       argc ++;
                do {
                        if(c == ';') {
                                if(j == Len)    return 0;
@@ -334,11 +368,25 @@ int Term_HandleVT100_Long(tTerminal *Term, int Len, const char *Buffer)
                        case  1:        // Aplication cursor keys
                                _SysDebug("TODO: \\e[?1%c Application cursor keys", c);
                                break;
+                       case  3:        // 132 Column mode
+                               _SysDebug("TODO: \\e[?3%c 132 Column mode", c);
+                               break;
+                       case  4:        // Smooth (Slow) Scroll
+                               _SysDebug("TODO: \\e[?4%c Smooth (Slow) Scroll", c);
+                               break;
+                       case  5:        // Reverse Video
+                               _SysDebug("TODO: \\e[?5%c Reverse Video", c);
+                               break;
+                       case  6:        // Origin Mode
+                               _SysDebug("TODO: \\e[?6%c Origin Mode", c);
+                               break;
                        case 12:
-                               _SysDebug("TODO: \\e[?25%c Start/Stop blinking cursor", c);
+                               //_SysDebug("TODO: \\e[?25%c Start/Stop blinking cursor", c);
+                               //Display_SolidCursor(Term, !set);
                                break;
                        case 25:        // Hide cursor
-                               _SysDebug("TODO: \\e[?25%c Show/Hide cursor", c);
+                               //_SysDebug("TODO: \\e[?25%c Show/Hide cursor", c);
+                               //Display_ShowCursor(Term, set);
                                break;
                        case 1047:      // Alternate buffer
                                Display_ShowAltBuffer(Term, set);
@@ -424,6 +472,40 @@ int Term_HandleVT100_Long(tTerminal *Term, int Len, const char *Buffer)
                case 'T':       // Scroll down n=1
                        Display_ScrollDown(Term, (argc >= 1 ? args[0] : 1));
                        break;
+               case 'c':       // Send Device Attributes
+                       switch(args[0])
+                       {
+                       case 0: // Request attributes from terminal
+                               // "VT100 with Advanced Video Option" (same as screen returns)
+                               Display_SendInput(Term, "\x1b[?1;2c");
+                               break;
+                       default:
+                               _SysDebug("TODO: Request device attributes \\e[%ic", args[0]);
+                               break;
+                       }
+                       break;
+               case 'f':
+                       if( argc != 2 ) {
+                               Display_SetCursor(Term, 0, 0);
+                       }
+                       else {
+                               // Adjust 1-based cursor position to 0-based
+                               Display_SetCursor(Term, args[0]-1, args[1]-1);
+                       }
+                       break;
+               case 'h':
+               case 'l':
+                       for( int i = 0; i < argc; i ++ )
+                       {
+                               switch(args[i])
+                               {
+                               default:
+                                       _SysDebug("Unknown VT100 mode \e[%i%c",
+                                               args[i], c);
+                                       break;
+                               }
+                       }
+                       break;
                case 'm':
                        if( argc == 0 )
                        {
@@ -445,7 +527,16 @@ int Term_HandleVT100_Long(tTerminal *Term, int Len, const char *Buffer)
                                                Display_SetForeground( Term, caVT100Colours[st->CurFG + 8] );
                                                break;
                                        case 2:
-                                               _SysDebug("TODO: VT100 \\e[1m - Reverse");
+                                               _SysDebug("TODO: \\e[2m - Reverse");
+                                               break;
+                                       case 4:
+                                               _SysDebug("TODO: \\e[4m - Underscore");
+                                               break;
+                                       case 7:
+                                               _SysDebug("TODO: \\e[7m - Reverse");
+                                               break;
+                                       case 24:        // Not underlined
+                                       case 27:        // Not inverse
                                                break;
                                        case 30 ... 37:
                                                st->CurFG = args[i]-30;
@@ -463,12 +554,15 @@ int Term_HandleVT100_Long(tTerminal *Term, int Len, const char *Buffer)
                                                Display_SetBackground( Term, caVT100Colours[ st->CurBG ] );
                                                break;
                                        default:
-                                               _SysDebug("TODO: VT100 \\e[%im", args[i]);
+                                               _SysDebug("Unknown mode set \\e[%im", args[i]);
                                                break;
                                        } 
                                }
                        }
                        break;
+               // Device Status Report
+               case 'n':
+                       break;
                // Set scrolling region
                case 'r':
                        Display_SetScrollArea(Term, args[0], (args[1] - args[0]));

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