* vt100.c
* - VT100/xterm Emulation
*/
-#include <string.h>
#include <limits.h>
#include "include/vt100.h"
#include "include/display.h"
#include <ctype.h> // isalpha
-#include <acess/sys.h> // _SysDebug
+#ifdef KERNEL_VERSION
+# define _SysDebug(v...) Debug("VT100 "v)
+#else
+# include <acess/sys.h> // _SysDebug
+# include <string.h>
+# include <assert.h>
+#endif
const uint32_t caVT100Colours[] = {
- // Black, Red, Green, Yellow, Blue, Purple, Cyan, Gray
+ // Black, Red, Green, Yellow, Blue, Magenta, Cyan, Gray
// Same again, but bright
- 0x000000, 0x770000, 0x007700, 0x777700, 0x000077, 0x770077, 0x007777, 0xAAAAAAA,
- 0xCCCCCC, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFFF
+ 0x000000, 0x770000, 0x007700, 0x777700, 0x000077, 0x770077, 0x007777, 0xAAAAAA,
+ 0xCCCCCC, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF,
};
int Term_HandleVT100_Long(tTerminal *Term, int Len, const char *Buf);
{
// Handle VT100 (like) escape sequence
int new_bytes = min(MAX_VT100_ESCAPE_LEN - inc_len, Len);
- int ret = 0, old_inc_len = inc_len;
+ int ret = 0;
+ int old_inc_len = inc_len;
memcpy(inc_buf + inc_len, Buf, new_bytes);
+ if( new_bytes == 0 ) {
+ _SysDebug("Term_HandleVT100: Hit max? (Len=%i)", Len);
+ inc_len = 0;
+ return 0;
+ }
+
inc_len += new_bytes;
+ //_SysDebug("inc_buf = %i '%.*s'", inc_len, inc_len, inc_buf);
if( inc_len <= 1 )
return 1; // Skip 1 character (the '\x1b')
ret += 2;
}
break;
+ case 'D':
+ Display_ScrollDown(Term, 1);
+ ret = 2;
+ break;
+ case 'M':
+ Display_ScrollDown(Term, -1);
+ ret = 2;
+ break;
default:
ret = 2;
break;
if( ret != 0 ) {
inc_len = 0;
+ assert(ret > old_inc_len);
+ //_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
+ ret = new_bytes;
return ret;
}
switch( *Buf )
{
+ // TODO: Need to handle \t and ^A-Z
case '\b':
- Display_MoveCursor(Term, -1, 0);
+ Display_MoveCursor(Term, 0, -1);
Display_AddText(Term, 1, " ");
- Display_MoveCursor(Term, -1, 0);
- // TODO: Need to handle \t and ^A-Z
+ Display_MoveCursor(Term, 0, -1);
return 1;
case '\t':
// TODO: tab (get current cursor pos, space until multiple of 8)
return 1;
case '\n':
+ // TODO: Support disabling CR after NL
Display_Newline(Term, 1);
return 1;
case '\r':
- Display_MoveCursor(Term, INT_MIN, 0);
- return 1;
+ if( Len >= 2 && Buf[1] == '\n' ) {
+ Display_Newline(Term, 1);
+ return 2;
+ }
+ else {
+ Display_MoveCursor(Term, 0, INT_MIN);
+ return 1;
+ }
}
int ret = 0;
// Get Command
if( !isalpha(c) ) {
// Bother.
- _SysDebug("Unexpected char 0x%x in VT100 escape code", c);
- return 1;
+ _SysDebug("Unexpected char 0x%x in VT100 escape code '\\e[%.*s'", c,
+ Len, Buffer);
+ return j;
}
if( bQuestionMark )
case 'l': // unset
switch(args[0])
{
+ case 1: // Aplication cursor keys
+ _SysDebug("TODO: \\e[?1%c Application cursor keys", c);
+ break;
case 25: // Hide cursor
_SysDebug("TODO: \\e[?25%c Show/Hide cursor", c);
break;
// Standard commands
switch( c )
{
+ case 'A':
+ Display_MoveCursor(Term, -(argc >= 1 ? args[0] : 1), 0);
+ break;
+ case 'B':
+ Display_MoveCursor(Term, (argc >= 1 ? args[0] : 1), 0);
+ break;
+ case 'C':
+ Display_MoveCursor(Term, 0, (argc >= 1 ? args[0] : 1));
+ break;
+ case 'D':
+ Display_MoveCursor(Term, 0, -(argc >= 1 ? args[0] : 1));
+ break;
case 'H':
if( argc != 2 ) {
}
Display_SetCursor(Term, args[0], args[1]);
}
break;
- case 'J':
- if( argc == 0 )
+ case 'J': // Clear lines
+ switch( args[0] )
+ {
+ case 0:
+ Display_ClearLines(Term, 1); // Down
+ break;
+ case 1:
+ Display_ClearLines(Term, -1); // Up
+ break;
+ case 2:
+ Display_ClearLines(Term, 0); // All
+ break;
+ default:
+ _SysDebug("Unknown VT100 %i J", args[0]);
+ break;
+ }
+ break;
+ case 'K':
+ switch( args[0] )
+ {
+ case 0: // To EOL
+ Display_ClearLine(Term, -1);
+ break;
+ case 1: // To SOL
+ Display_ClearLine(Term, 1);
+ break;
+ case 2:
Display_ClearLine(Term, 0);
- else if( args[0] == 2 )
- Display_ClearLines(Term, 0); // Entire screen!
- else
- _SysDebug("TODO: VT100 %i J", args[0]);
+ break;
+ default:
+ _SysDebug("Unknown VT100 %i K", args[0]);
+ break;
+ }
+ case 'S': // Scroll down n=1
+ Display_ScrollDown(Term, -(argc >= 1 ? args[0] : 1));
break;
case 'T': // Scroll down n=1
- _SysDebug("TODO: \\x1B[nT - Scroll down");
+ Display_ScrollDown(Term, (argc >= 1 ? args[0] : 1));
break;
case 'm':
if( argc == 0 )
{
// Reset
+ Display_ResetAttributes(Term);
}
else
{
- int i;
- for( i = 0; i < argc; i ++ )
+ for( int i = 0; i < argc; i ++ )
{
- if( args[i] < 8 )
- {
- // TODO: Flags?
- }
- else if( 30 <= args[i] && args[i] <= 37 )
+ switch(args[i])
{
+ case 0:
+ Display_ResetAttributes(Term);
+ break;
+ case 1:
+ _SysDebug("TODO: VT100 \\e[1m - Bold");
+ break;
+ case 2:
+ _SysDebug("TODO: VT100 \\e[1m - Reverse");
+ break;
+ case 30 ... 37:
// TODO: Bold/bright
Display_SetForeground( Term, caVT100Colours[ args[i]-30 ] );
- }
- else if( 40 <= args[i] && args[i] <= 47 )
- {
+ break;
+ case 40 ... 47:
// TODO: Bold/bright
- Display_SetBackground( Term, caVT100Colours[ args[i]-30 ] );
+ Display_SetBackground( Term, caVT100Colours[ args[i]-40 ] );
+ break;
+ default:
+ _SysDebug("TODO: VT100 \\e[%im", args[i]);
+ break;
}
}
}
break;
// Set scrolling region
case 'r':
- _SysDebug("TODO: \\x1B[%i;%ir - Set Scroll Region",
- args[0], args[1]);
+ Display_SetScrollArea(Term, args[0], (args[1] - args[0]));
+ break;
+
+ case 's':
+ Display_SaveCursor(Term);
+ break;
+ case 'u':
+ Display_RestoreCursor(Term);
break;
default:
_SysDebug("Unknown VT100 long escape char 0x%x '%c'", c, c);