#include <errno.h>
#include <semaphore.h>
-#define USE_CTRL_ALT 1
-
// === CONSTANTS ===
#define VERSION ((0<<8)|(50))
#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 {
}
/**
- * \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)
// 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;
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)
// 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 )
break;
}
break;
+ default:
+ Log_Warning("VTerm", "Unknown control sequence '\\x1B[?%c'", c);
+ break;
}
}
else
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 )
Term->AltWritePos = args[0] + args[1]*Term->TextWidth;
else
Term->WritePos = args[0] + args[1]*Term->TextWidth;
- Log_Debug("VTerm", "args = {%i, %i}", args[0], args[1]);
+ //Log_Debug("VTerm", "args = {%i, %i}", args[0], args[1]);
break;
// Scroll up `n` lines
case 'S':
tmp = -1;
// Scroll down `n` lines
- case 'P':
+ case 'T':
if(argc == 1) tmp *= args[0];
-
+ if( Term->Flags & VT_FLAG_ALTBUF )
+ VT_int_ScrollText(Term, tmp);
+ else
+ {
+ if(Term->ViewPos/Term->TextWidth + tmp < 0)
+ break;
+ if(Term->ViewPos/Term->TextWidth + tmp > Term->TextHeight * (giVT_Scrollback + 1))
+ break;
+
+ Term->ViewPos += Term->TextWidth*tmp;
+ }
break;
// Set Font flags
break;
default:
- Log_Warning("VTerm", "Unknown control sequence");
+ Log_Warning("VTerm", "Unknown control sequence '\\x1B[%c'", c);
break;
}
}
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
// Update the last line
Term->WritePos -= Term->TextWidth;
VT_int_UpdateScreen( Term, 0 );
+ Term->WritePos += Term->TextWidth;
VT_int_ScrollText(Term, 1);
+
+ Term->ViewPos += Term->TextWidth;
}
}
{
tVT_Char *buf;
int height, init_write_pos;
- int base, len, i;
+ int len, i;
if( Term->Flags & VT_FLAG_ALTBUF )
{
if( Count > 0 )
{
+ int base;
if(Count > Term->ScrollHeight) Count = Term->ScrollHeight;
base = Term->TextWidth*(Term->ScrollTop + Term->ScrollHeight - Count);
- len = Term->TextWidth*(height - Term->ScrollHeight - Count - Term->ScrollTop);
+ len = Term->TextWidth*(Term->ScrollHeight - Count);
// Scroll terminal cache
memcpy(
// Update Screen
VT_int_ScrollFramebuffer( Term, Count );
- Term->WritePos = Term->ViewPos + Term->ScrollTop + (Term->ScrollHeight - Count);
+ if( Term->Flags & VT_FLAG_ALTBUF )
+ 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 );
Count = -Count;
if(Count > Term->ScrollHeight) Count = Term->ScrollHeight;
- len = Term->TextWidth*(height - Term->ScrollHeight - Count - Term->ScrollTop);
+ len = Term->TextWidth*(Term->ScrollHeight - Count);
// Scroll terminal cache
memcpy(
}
VT_int_ScrollFramebuffer( Term, -Count );
- Term->WritePos = Term->ViewPos + Term->ScrollTop;
+ if( Term->Flags & VT_FLAG_ALTBUF )
+ Term->AltWritePos = Term->TextWidth*Term->ScrollTop;
+ else
+ Term->WritePos = Term->ViewPos + Term->TextWidth*Term->ScrollTop;
for( i = 0; i < Count; i ++ )
{
VT_int_UpdateScreen( Term, 0 );
{
buf.SrcY = (Term->ScrollTop+Count) * giVT_CharHeight;
buf.DstY = Term->ScrollTop * giVT_CharHeight;
- buf.H = (Term->ScrollHeight-Count) * giVT_CharHeight;
}
else // Scroll up, move text down
{
+ Count = -Count;
buf.SrcY = Term->ScrollTop * giVT_CharHeight;
buf.DstY = (Term->ScrollTop+Count) * giVT_CharHeight;
- buf.H = (Term->ScrollHeight+Count) * giVT_CharHeight;
}
+ buf.H = (Term->ScrollHeight-Count) * giVT_CharHeight;
VFS_WriteAt(giVT_OutputDevHandle, 0, sizeof(buf), &buf);
// Restore old mode (this function is only called during text mode)
Term->Flags |= VT_FLAG_ALTBUF;
else
Term->Flags &= ~VT_FLAG_ALTBUF;
+ VT_int_UpdateScreen(Term, 1);
}
// ---