X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Fgui_shell_src%2Fvt100.c;h=cad4119494d3f705d7c705b5868cd59a0212df29;hb=3efa0bc1d46a4bcda04763a89d54a6802e717231;hp=51c8016fe342c10fc25a29f6ffa3a5d5e1eae68d;hpb=f194730e75d6d3681e5f99a4efed1616fd1ea738;p=tpg%2Facess2.git diff --git a/Usermode/Applications/gui_shell_src/vt100.c b/Usermode/Applications/gui_shell_src/vt100.c index 51c8016f..cad41194 100644 --- a/Usermode/Applications/gui_shell_src/vt100.c +++ b/Usermode/Applications/gui_shell_src/vt100.c @@ -2,53 +2,234 @@ * Acess GUI Terminal * - By John Hodge (thePowersGang) * - * main.c - * - Core + * vt100.c + * - VT100/xterm Emulation */ #include +#include #include "include/vt100.h" #include "include/display.h" +#include // isalpha +#include // _SysDebug -int Term_HandleVT100(int Len, const char *Buf) +const uint32_t caVT100Colours[] = { + // Black, Red, Green, Yellow, Blue, Purple, Cyan, Gray + // Same again, but bright + 0x000000, 0x770000, 0x007700, 0x777700, 0x000077, 0x770077, 0x007777, 0xAAAAAAA, + 0xCCCCCC, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFFF +}; + + int Term_HandleVT100_Long(tTerminal *Term, int Len, const char *Buf); + +static inline int min(int a, int b) +{ + return a < b ? a : b; +} + +int Term_HandleVT100(tTerminal *Term, int Len, const char *Buf) { - const int max_length = 16; - static char inc_buf[max_length] + #define MAX_VT100_ESCAPE_LEN 16 + static char inc_buf[MAX_VT100_ESCAPE_LEN]; static int inc_len = 0; if( inc_len > 0 || *Buf == '\x1b' ) { - memcpy(inc_buf + inc_len, Buf, min(max_length - inc_len, Len)); // Handle VT100 (like) escape sequence - - inc_len = 0; - return 1; + int new_bytes = min(MAX_VT100_ESCAPE_LEN - inc_len, Len); + int ret = 0, old_inc_len = inc_len; + memcpy(inc_buf + inc_len, Buf, new_bytes); + + inc_len += new_bytes; + + if( inc_len <= 1 ) + return 1; // Skip 1 character (the '\x1b') + + switch(inc_buf[1]) + { + case '[': // Multibyte, funtime starts + ret = Term_HandleVT100_Long(Term, inc_len-2, inc_buf+2); + if( ret > 0 ) { + ret += 2; + } + break; + default: + ret = 2; + break; + } + + if( ret != 0 ) { + inc_len = 0; + ret -= old_inc_len; // counter cached bytes + } + return ret; } switch( *Buf ) { case '\b': - // TODO: Backspace + Display_MoveCursor(Term, -1, 0); + Display_AddText(Term, 1, " "); + Display_MoveCursor(Term, -1, 0); + // TODO: Need to handle \t and ^A-Z return 1; case '\t': - // TODO: tab + // TODO: tab (get current cursor pos, space until multiple of 8) return 1; case '\n': - Display_Newline(1); + Display_Newline(Term, 1); return 1; case '\r': - // TODO: Carriage return - return ; + Display_MoveCursor(Term, INT_MIN, 0); + return 1; } int ret = 0; while( ret < Len ) { - if( *Buf == '\n' ) + switch(*Buf) + { + case '\x1b': + case '\b': + case '\t': + case '\n': + case '\r': + // Force an exit right now + Len = ret; break; - if( *Buf == '\x1b' ) + default: + ret ++; + Buf ++; break; - ret ++; - Buf ++; + } } return -ret; } + +int Term_HandleVT100_Long(tTerminal *Term, int Len, const char *Buffer) +{ + char c; + int argc = 0, j = 0; + int args[6] = {0,0,0,0,0,0}; + int bQuestionMark = 0; + + // Get Arguments + if(j == Len) return 0; + c = Buffer[j++]; + if(c == '?') { + bQuestionMark = 1; + if(j == Len) return 0; + c = Buffer[j++]; + } + if( '0' <= c && c <= '9' ) + { + do { + if(c == ';') { + if(j == Len) return 0; + c = Buffer[j++]; + } + while('0' <= c && c <= '9') { + args[argc] *= 10; + args[argc] += c-'0'; + if(j == Len) return 0; + c = Buffer[j++]; + } + argc ++; + } while(c == ';'); + } + + // Get Command + if( !isalpha(c) ) { + // Bother. + _SysDebug("Unexpected char 0x%x in VT100 escape code", c); + return 1; + } + + if( bQuestionMark ) + { + int set = 0; + // Special commands + switch( c ) + { + case 'h': // set + set = 1; + case 'l': // unset + switch(args[0]) + { + case 25: // Hide cursor + _SysDebug("TODO: \\e[?25%c Show/Hide cursor", c); + break; + case 1047: // Alternate buffer + Display_ShowAltBuffer(Term, set); + break; + default: + _SysDebug("TODO: \\e[?%i%c Unknow DEC private mode", args[0], c); + break; + } + break; + default: + _SysDebug("Unknown VT100 extended escape char 0x%x", c); + break; + } + } + else + { + // Standard commands + switch( c ) + { + case 'H': + if( argc != 2 ) { + } + else { + Display_SetCursor(Term, args[0], args[1]); + } + break; + case 'J': + if( argc == 0 ) + Display_ClearLine(Term, 0); + else if( args[0] == 2 ) + Display_ClearLines(Term, 0); // Entire screen! + else + _SysDebug("TODO: VT100 %i J", args[0]); + break; + case 'T': // Scroll down n=1 + _SysDebug("TODO: \\x1B[nT - Scroll down"); + break; + case 'm': + if( argc == 0 ) + { + // Reset + } + else + { + int i; + for( i = 0; i < argc; i ++ ) + { + if( args[i] < 8 ) + { + // TODO: Flags? + } + else if( 30 <= args[i] && args[i] <= 37 ) + { + // TODO: Bold/bright + Display_SetForeground( Term, caVT100Colours[ args[i]-30 ] ); + } + else if( 40 <= args[i] && args[i] <= 47 ) + { + // TODO: Bold/bright + Display_SetBackground( Term, caVT100Colours[ args[i]-30 ] ); + } + } + } + break; + // Set scrolling region + case 'r': + _SysDebug("TODO: \\x1B[%i;%ir - Set Scroll Region", + args[0], args[1]); + break; + default: + _SysDebug("Unknown VT100 long escape char 0x%x '%c'", c, c); + break; + } + } + return j; +}