#define VT_FLAG_HASFB 0x10 //!< Set if the VTerm has requested the Framebuffer
enum eVT_InModes {
- VT_INMODE_TEXT8, // UTF-8 Text Mode (VT100 Emulation)
+ VT_INMODE_TEXT8, // UTF-8 Text Mode (VT100/xterm Emulation)
VT_INMODE_TEXT32, // UTF-32 Text Mode (Acess Native)
NUM_VT_INMODES
};
} tVTerm;
// === IMPORTS ===
-extern void Debug_SetKTerminal(char *File);
+extern void Debug_SetKTerminal(const char *File);
// === PROTOTYPES ===
int VT_Install(char **Arguments);
void VT_SetTerminal(int ID);
void VT_KBCallBack(Uint32 Codepoint);
void VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count);
+void VT_int_ClearLine(tVTerm *Term, int Num);
int VT_int_ParseEscape(tVTerm *Term, char *Buffer);
void VT_int_PutChar(tVTerm *Term, Uint32 Ch);
void VT_int_ScrollFramebuffer( tVTerm *Term );
// Scan Arguments
if(Arguments)
{
- char **args = Arguments;
- char *arg, *opt, *val;
- for( ; (arg = *args); args++ )
+ char **args;
+ const char *arg;
+ for(args = Arguments; (arg = *args); args++ )
{
+ char data[strlen(arg)+1];
+ char *opt = data;
+ char *val;
+
+ val = strchr(arg, '=');
+ strcpy(data, arg);
+ if( val ) {
+ data[ val - arg ] = '\0';
+ val ++;
+ }
Log_Debug("VTerm", "Argument '%s'", arg);
- opt = arg;
- val = arg + strpos(arg, '='); *val++ = '\0';
if( strcmp(opt, "Video") == 0 ) {
- gsVT_OutputDevice = val;
+ gsVT_OutputDevice = strdup(val);
}
else if( strcmp(opt, "Input") == 0 ) {
- gsVT_InputDevice = val;
+ gsVT_InputDevice = strdup(val);
}
else if( strcmp(opt, "Width") == 0 ) {
giVT_RealWidth = atoi( val );
if(gsVT_InputDevice) Modules_InitialiseBuiltin( gsVT_InputDevice );
// Apply Defaults
- if(!gsVT_OutputDevice) gsVT_OutputDevice = DEFAULT_OUTPUT;
- if(!gsVT_InputDevice) gsVT_InputDevice = DEFAULT_INPUT;
+ if(!gsVT_OutputDevice) gsVT_OutputDevice = strdup(DEFAULT_OUTPUT);
+ if(!gsVT_InputDevice) gsVT_InputDevice = strdup(DEFAULT_INPUT);
// Create paths
{
gVT_Terminals[i].CurColour = DEFAULT_COLOUR;
gVT_Terminals[i].WritePos = 0;
gVT_Terminals[i].ViewPos = 0;
+ gVT_Terminals[i].ReadingThread = -1;
// Initialise
VT_int_ChangeMode( &gVT_Terminals[i],
void VT_InitOutput()
{
giVT_OutputDevHandle = VFS_Open(gsVT_OutputDevice, VFS_OPENFLAG_WRITE);
- if(giVT_InputDevHandle == -1) {
+ if(giVT_OutputDevHandle == -1) {
Log_Warning("VTerm", "Oh F**k, I can't open the video device '%s'", gsVT_OutputDevice);
return ;
}
void VT_InitInput()
{
giVT_InputDevHandle = VFS_Open(gsVT_InputDevice, VFS_OPENFLAG_READ);
- if(giVT_InputDevHandle == -1) return ;
+ if(giVT_InputDevHandle == -1) {
+ Log_Warning("VTerm", "Can't open the input device '%s'", gsVT_InputDevice);
+ return ;
+ }
VFS_IOCtl(giVT_InputDevHandle, KB_IOCTL_SETCALLBACK, VT_KBCallBack);
}
len = strlen(Data);
+ // TODO: Check if the string used is a heap string
+
free(gsVT_OutputDevice);
gsVT_OutputDevice = malloc(len+1);
if( term->NewHeight )
ret = term->NewHeight;
else if( term->Mode == TERM_MODE_TEXT )
- ret = term->TextHeight = *iData;
+ ret = term->TextHeight;
else
ret = term->Height;
LEAVE('i', ret);
{
int i;
tVT_Char *cell = &Term->Text[ Num*Term->TextWidth ];
- if( Num < 0 || Num >= Term->TextHeight ) return ;
+ if( Num < 0 || Num >= Term->TextHeight * (giVT_Scrollback + 1) ) return ;
//ENTER("pTerm iNum", Term, Num);
for( i = Term->TextWidth; i--; )
{
void VT_int_PutChar(tVTerm *Term, Uint32 Ch)
{
int i;
-
+
switch(Ch)
{
case '\0': return; // Ignore NULL byte
// - Check if we need to scroll the entire scrollback buffer
if(Term->WritePos >= Term->TextWidth*Term->TextHeight*(giVT_Scrollback+1))
{
- int base, i;
-
- //Debug("Scrolling entire buffer");
+ int base;
// Move back by one
Term->WritePos -= Term->TextWidth;
Term->WritePos -= Term->TextWidth;
VT_int_UpdateScreen( Term, 0 );
Term->WritePos += Term->TextWidth;
+ VT_int_ClearLine(Term, Term->WritePos / Term->TextWidth);
// Scroll
Term->ViewPos += Term->TextWidth;
// === CODE ===
/**
- * \fn void VT_Font_Render(Uint32 Codepoint, void *Buffer, int Pitch, Uint32 BGC, Uint32 FGC)
* \brief Render a font character
*/
-void VT_Font_Render(Uint32 Codepoint, void *Buffer, int Pitch, Uint32 BGC, Uint32 FGC)
+void VT_Font_Render(Uint32 Codepoint, void *Buffer, int Depth, int Pitch, Uint32 BGC, Uint32 FGC)
{
Uint8 *font;
- Uint32 *buf = Buffer;
int x, y;
- font = VT_Font_GetChar(Codepoint);
-
- for(y = 0; y < FONT_HEIGHT; y ++)
+ // 8-bpp and below
+ if( Depth <= 8 )
{
- for(x = 0; x < FONT_WIDTH; x ++)
+ Uint8 *buf = Buffer;
+
+ font = VT_Font_GetChar(Codepoint);
+
+ for(y = 0; y < FONT_HEIGHT; y ++)
{
- if(*font & (1 << (FONT_WIDTH-x-1)))
- buf[x] = FGC;
- else
- buf[x] = BGC;
+ for(x = 0; x < FONT_WIDTH; x ++)
+ {
+ if(*font & (1 << (FONT_WIDTH-x-1)))
+ buf[x] = FGC;
+ else
+ buf[x] = BGC;
+ }
+ buf = (void*)( (tVAddr)buf + Pitch );
+ font ++;
+ }
+ }
+ // 16-bpp and below
+ else if( Depth <= 16 )
+ {
+ Uint16 *buf = Buffer;
+
+ font = VT_Font_GetChar(Codepoint);
+
+ for(y = 0; y < FONT_HEIGHT; y ++)
+ {
+ for(x = 0; x < FONT_WIDTH; x ++)
+ {
+ if(*font & (1 << (FONT_WIDTH-x-1)))
+ buf[x] = FGC;
+ else
+ buf[x] = BGC;
+ }
+ buf = (void*)( (tVAddr)buf + Pitch );
+ font ++;
+ }
+ }
+ // 24-bpp colour
+ // - Special handling to not overwrite the next pixel
+ //TODO: Endian issues here
+ else if( Depth == 24 )
+ {
+ Uint8 *buf = Buffer;
+ Uint8 bg_r = (BGC >> 16) & 0xFF;
+ Uint8 bg_g = (BGC >> 8) & 0xFF;
+ Uint8 bg_b = (BGC >> 0) & 0xFF;
+ Uint8 fg_r = (FGC >> 16) & 0xFF;
+ Uint8 fg_g = (FGC >> 8) & 0xFF;
+ Uint8 fg_b = (FGC >> 0) & 0xFF;
+
+ font = VT_Font_GetChar(Codepoint);
+
+ for(y = 0; y < FONT_HEIGHT; y ++)
+ {
+ for(x = 0; x < FONT_WIDTH; x ++)
+ {
+ Uint8 r, g, b;
+
+ if(*font & (1 << (FONT_WIDTH-x-1))) {
+ r = fg_r; g = fg_g; b = fg_b;
+ }
+ else {
+ r = bg_r; g = bg_g; b = bg_b;
+ }
+ buf[x*3+0] = b;
+ buf[x*3+1] = g;
+ buf[x*3+2] = r;
+ }
+ buf = (void*)( (tVAddr)buf + Pitch );
+ font ++;
+ }
+ }
+ // 32-bpp colour (nice and easy)
+ else if( Depth == 32 )
+ {
+ Uint32 *buf = Buffer;
+
+ font = VT_Font_GetChar(Codepoint);
+
+ for(y = 0; y < FONT_HEIGHT; y ++)
+ {
+ for(x = 0; x < FONT_WIDTH; x ++)
+ {
+ if(*font & (1 << (FONT_WIDTH-x-1)))
+ buf[x] = FGC;
+ else
+ buf[x] = BGC;
+ }
+ buf = (Uint32*)( (tVAddr)buf + Pitch );
+ font ++;
}
- buf += Pitch;
- font ++;
}
}
/**
* \fn Uint32 VT_Colour12to24(Uint16 Col12)
- * \brief Converts a
+ * \brief Converts a 12-bit colour into 24 bits
*/
Uint32 VT_Colour12to24(Uint16 Col12)
{
ret |= (tmp << 16) | (tmp << 20);
return ret;
}
+/**
+ * \brief Converts a 12-bit colour into 15 bits
+ */
+Uint16 VT_Colour12to15(Uint16 Col12)
+{
+ Uint32 ret;
+ int tmp;
+ tmp = Col12 & 0xF;
+ ret = (tmp << 1) | (tmp & 1);
+ tmp = (Col12 & 0xF0) >> 4;
+ ret |= ( (tmp << 1) | (tmp & 1) ) << 5;
+ tmp = (Col12 & 0xF00) >> 8;
+ ret |= ( (tmp << 1) | (tmp & 1) ) << 10;
+ return ret;
+}
+
+/**
+ * \brief Converts a 12-bit colour into any other depth
+ * \param Col12 12-bit source colour
+ * \param Depth Desired bit deptj
+ * \note Green then blue get the extra avaliable bits (16:5-6-5, 14:4-5-5)
+ */
+Uint32 VT_Colour12toN(Uint16 Col12, int Depth)
+{
+ Uint32 ret;
+ Uint32 r, g, b;
+ int rSize, gSize, bSize;
+
+ // Fast returns
+ if( Depth == 24 ) return VT_Colour12to24(Col12);
+ if( Depth == 15 ) return VT_Colour12to15(Col12);
+
+ // Bounds checks
+ if( Depth < 8 ) return 0;
+ if( Depth > 32 ) return 0;
+
+ r = Col12 & 0xF;
+ g = (Col12 & 0xF0) >> 4;
+ b = (Col12 & 0xF00) >> 8;
+
+ rSize = gSize = bSize = Depth / 3;
+ if( rSize + gSize + bSize < Depth ) // Depth % 3 == 1
+ gSize ++;
+ if( rSize + gSize + bSize < Depth ) // Depth % 3 == 2
+ bSize ++;
+
+ // Expand
+ r <<= rSize - 4; g <<= gSize - 4; b <<= bSize - 4;
+ // Fill with the lowest bit
+ if( Col12 & 0x001 ) r |= (1 << (rSize - 4)) - 1;
+ if( Col12 & 0x010 ) r |= (1 << (gSize - 4)) - 1;
+ if( Col12 & 0x100 ) r |= (1 << (bSize - 4)) - 1;
+
+ // Create output
+ ret = r;
+ ret |= g << rSize;
+ ret |= b << (rSize + gSize);
+
+ return ret;
+}
/**
* \fn Uint8 *VT_Font_GetChar(Uint32 Codepoint)