#include <tpl_drv_keyboard.h>
#include <tpl_drv_terminal.h>
#include <errno.h>
+#include <semaphore.h>
#define USE_CTRL_ALT 0
int InputRead; //!< Input buffer read position
int InputWrite; //!< Input buffer write position
char InputBuffer[MAX_INPUT_CHARS8];
+ tSemaphore InputSemaphore;
tVT_Char *Text;
Uint32 *Buffer;
gVT_Terminals[i].Node.Read = VT_Read;
gVT_Terminals[i].Node.Write = VT_Write;
gVT_Terminals[i].Node.IOCtl = VT_Terminal_IOCtl;
+ Semaphore_Init(&gVT_Terminals[i].InputSemaphore, 0, MAX_INPUT_CHARS8, "VTerm", gVT_Terminals[i].Name);
}
// Add to DevFS
tVTerm *term = &gVT_Terminals[ Node->Inode ];
Mutex_Acquire( &term->ReadingLock );
- term->ReadingThread = Threads_GetTID();
// Check current mode
switch(term->Mode)
case TERM_MODE_TEXT:
while(pos < Length)
{
- //TODO: Sleep instead
- while(term->InputRead == term->InputWrite) Threads_Sleep();
+ int avail_bytes;
+ VFS_SelectNode(Node, VFS_SELECT_READ, NULL);
+ avail_bytes = term->InputRead - term->InputWrite;
+
+ if(avail_bytes < 0)
+ avail_bytes += MAX_INPUT_CHARS8;
+ if(avail_bytes > Length - pos)
+ avail_bytes = Length - pos;
- ((char*)Buffer)[pos] = term->InputBuffer[term->InputRead];
- pos ++;
- term->InputRead ++;
- term->InputRead %= MAX_INPUT_CHARS8;
+ while( avail_bytes -- )
+ {
+ ((char*)Buffer)[pos] = term->InputBuffer[term->InputRead];
+ pos ++;
+ term->InputRead ++;
+ term->InputRead %= MAX_INPUT_CHARS8;
+ }
}
break;
default:
while(pos < Length)
{
- while(term->InputRead == term->InputWrite) Threads_Sleep();
- ((Uint32*)Buffer)[pos] = ((Uint32*)term->InputBuffer)[term->InputRead];
- pos ++;
- term->InputRead ++;
- term->InputRead %= MAX_INPUT_CHARS32;
+ int avail;
+ VFS_SelectNode(Node, VFS_SELECT_READ, NULL);
+
+ avail = term->InputRead - term->InputWrite;
+ if(avail < 0)
+ avail += MAX_INPUT_CHARS32;
+ if(avail > Length - pos)
+ avail = Length/4 - pos;
+
+
+ while( avail -- )
+ {
+ ((Uint32*)Buffer)[pos] = ((Uint32*)term->InputBuffer)[term->InputRead];
+ pos ++;
+ term->InputRead ++;
+ term->InputRead %= MAX_INPUT_CHARS32;
+ }
}
+ pos *= 4;
break;
}
+ // Mark none avaliable if buffer empty
+ if( term->InputRead == term->InputWrite )
+ VFS_MarkAvaliable(&term->Node, 0);
+
term->ReadingThread = -1;
+
Mutex_Release( &term->ReadingLock );
- return 0;
+ return pos;
}
/**
term->InputRead = term->InputWrite + 1;
term->InputRead %= MAX_INPUT_CHARS8;
}
-
}
else
{
}
}
+ VFS_MarkAvaliable(&term->Node, 1);
+
// Wake up the thread waiting on us
- if( term->ReadingThread >= 0 ) {
- Threads_WakeTID(term->ReadingThread);
- }
+ //if( term->ReadingThread >= 0 ) {
+ // Threads_WakeTID(term->ReadingThread);
+ //}
}
/**
// === 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);
+ // - 32 is a special case, it's usually 24-bit colour with an unused byte
+ if( Depth == 32 ) return VT_Colour12to24(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)