X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fdrv%2Fvterm.c;h=b26113089478810a1f501c6d9d7d84afe95e1ea9;hb=e42035c38b65d428672b128f9ae253f81b2ced96;hp=db56f0e7765ddfd443c9647ff01c073c456d56b4;hpb=9d85201216cb35e1b1e051b1d7cdc38eaa5befa4;p=tpg%2Facess2.git diff --git a/Kernel/drv/vterm.c b/Kernel/drv/vterm.c index db56f0e7..b2611308 100644 --- a/Kernel/drv/vterm.c +++ b/Kernel/drv/vterm.c @@ -9,6 +9,7 @@ #include #include #include +#include #define USE_CTRL_ALT 0 @@ -56,6 +57,7 @@ typedef struct { int InputRead; //!< Input buffer read position int InputWrite; //!< Input buffer write position char InputBuffer[MAX_INPUT_CHARS8]; + tSemaphore InputSemaphore; tVT_Char *Text; Uint32 *Buffer; @@ -221,6 +223,7 @@ int VT_Install(char **Arguments) 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 @@ -419,7 +422,6 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) tVTerm *term = &gVT_Terminals[ Node->Inode ]; Mutex_Acquire( &term->ReadingLock ); - term->ReadingThread = Threads_GetTID(); // Check current mode switch(term->Mode) @@ -428,13 +430,22 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) 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; @@ -443,19 +454,37 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) 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; } /** @@ -830,7 +859,6 @@ void VT_KBCallBack(Uint32 Codepoint) term->InputRead = term->InputWrite + 1; term->InputRead %= MAX_INPUT_CHARS8; } - } else { @@ -844,10 +872,12 @@ void VT_KBCallBack(Uint32 Codepoint) } } + 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); + //} } /** @@ -1328,34 +1358,113 @@ int giVT_CharHeight = FONT_HEIGHT; // === 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) { @@ -1369,6 +1478,68 @@ 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)