X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fdrv%2Fvterm.c;h=8255f6c79564b7886ea1f36f20caf8a485cd962c;hb=f9c3c4a68ba22b00df9441631a8513198c8859a5;hp=5c88786bd5352dceb6d34428468cf2740627c435;hpb=cea789b7006552c5365744d4ebaddbdc96387355;p=tpg%2Facess2.git diff --git a/Kernel/drv/vterm.c b/Kernel/drv/vterm.c index 5c88786b..8255f6c7 100644 --- a/Kernel/drv/vterm.c +++ b/Kernel/drv/vterm.c @@ -1,7 +1,7 @@ /* * Acess2 Virtual Terminal Driver */ -#define DEBUG 1 +#define DEBUG 0 #include #include #include @@ -20,8 +20,8 @@ #define MAX_INPUT_CHARS8 (MAX_INPUT_CHARS32*4) #define VT_SCROLLBACK 2 // 2 Screens of text //#define DEFAULT_OUTPUT "VGA" -#define DEFAULT_OUTPUT "BochsGA" -//#define DEFAULT_OUTPUT "Vesa" +//#define DEFAULT_OUTPUT "BochsGA" +#define DEFAULT_OUTPUT "Vesa" #define DEFAULT_INPUT "PS2Keyboard" #define DEFAULT_WIDTH 80 #define DEFAULT_HEIGHT 25 @@ -63,6 +63,8 @@ extern void Debug_SetKTerminal(char *File); // === PROTOTYPES === int VT_Install(char **Arguments); +void VT_InitOutput(void); +void VT_InitInput(void); char *VT_ReadDir(tVFS_Node *Node, int Pos); tVFS_Node *VT_FindDir(tVFS_Node *Node, char *Name); int VT_Root_IOCtl(tVFS_Node *Node, int Id, void *Data); @@ -190,6 +192,9 @@ int VT_Install(char **Arguments) // Add to DevFS DevFS_AddDevice( &gVT_DrvInfo ); + VT_InitOutput(); + VT_InitInput(); + // Set kernel output to VT0 Debug_SetKTerminal("/Devices/VTerm/0"); @@ -204,8 +209,12 @@ int VT_Install(char **Arguments) void VT_InitOutput() { giVT_OutputDevHandle = VFS_Open(gsVT_OutputDevice, VFS_OPENFLAG_WRITE); + if(giVT_InputDevHandle == -1) { + Log_Warning("VTerm", "Oh F**k, I can't open the video device '%s'", gsVT_OutputDevice); + return ; + } VT_SetTerminal( 0 ); - VT_SetResolution(1, 640, 480); + VT_SetResolution(1, 640, 400); } /** @@ -344,6 +353,7 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) { tVTerm *term = &gVT_Terminals[ Node->Inode ]; + int size; // Write switch( term->Mode ) @@ -352,26 +362,44 @@ Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) VT_int_PutString(term, Buffer, Length); break; case TERM_MODE_FB: - if( giVT_RealWidth > term->Width || giVT_RealHeight > term->Height ) + size = term->Width*term->Height*4; + if( Offset > size ) { + Log_Notice("VTerm", "VT_Write: Offset (0x%llx) > FBSize (0x%x)", + Offset, size); + return 0; + } + + if( Offset + Length > size ) { + Log_Notice("VTerm", "VT_Write: Offset+Length (0x%llx) > FBSize (0x%x)", + Offset+Length, size); + Length = size - Offset; + } + + memcpy( (void*)((Uint)term->Buffer + (Uint)Offset), Buffer, Length ); + + if( Node->Inode == giVT_CurrentTerminal ) { - #if 0 - int x, y, h; - x = Offset/4; y = x / term->Width; x %= term->Width; - w = Length/4+x; h = w / term->Width; w %= term->Width; - while(h--) + if( giVT_RealWidth > term->Width || giVT_RealHeight > term->Height ) { - VFS_WriteAt( giVT_OutputDevHandle, - (x+y*term->RealWidth)*4, - term->Width * 4, - Buffer - ); - Buffer = (void*)( (Uint)Buffer + term->Width*term->Height*4 ); + #if 0 + int x, y, h; + x = Offset/4; y = x / term->Width; x %= term->Width; + w = Length/4+x; h = w / term->Width; w %= term->Width; + while(h--) + { + VFS_WriteAt( giVT_OutputDevHandle, + (x+y*term->RealWidth)*4, + term->Width * 4, + Buffer + ); + Buffer = (void*)( (Uint)Buffer + term->Width*term->Height*4 ); + } + #endif + return 0; + } + else { + return VFS_WriteAt( giVT_OutputDevHandle, Offset, Length, Buffer ); } - #endif - return 0; - } - else { - return VFS_WriteAt( giVT_OutputDevHandle, Offset, Length, Buffer ); } } @@ -389,6 +417,8 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data) ENTER("pNode iId pData", Node, Id, Data); if(Id >= DRV_IOCTL_LOOKUP) { + // Only root can fiddle with graphics modes + // TODO: Remove this and replace with user ownership if( Threads_GetUID() != 0 ) return -1; } @@ -412,11 +442,13 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data) case TERM_IOCTL_MODETYPE: if(Data != NULL) { + Log_Log("VTerm", "VTerm %i mode set to %i", (int)Node->Inode, *iData); + // Update mode if needed if(term->Mode != *iData) VT_int_ChangeMode(term, *iData); // Update the screen dimensions - if(giVT_CurrentTerminal == Node->Inode) + if(Node->Inode == giVT_CurrentTerminal) VT_SetTerminal( giVT_CurrentTerminal ); } LEAVE('i', term->Mode); @@ -437,6 +469,8 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data) return term->Height; case TERM_IOCTL_FORCESHOW: + Log_Log("VTerm", "Thread %i forced VTerm %i to be shown", + Threads_GetTID(), (int)Node->Inode); VT_SetTerminal( Node->Inode ); LEAVE('i', 1); return 1; @@ -463,12 +497,7 @@ void VT_SetResolution(int IsTextMode, int Width, int Height) giVT_RealHeight = mode.height; VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_GETSETMODE, &tmp ); - - - if(IsTextMode) - tmp = VIDEO_BUFFMT_TEXT; - else - tmp = VIDEO_BUFFMT_FRAMEBUFFER; + tmp = IsTextMode ? VIDEO_BUFFMT_TEXT : VIDEO_BUFFMT_FRAMEBUFFER; VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &tmp ); } @@ -484,7 +513,7 @@ void VT_SetTerminal(int ID) gpVT_CurTerm = &gVT_Terminals[ID]; // Update cursor - if( !(gpVT_CurTerm->Flags & VT_FLAG_HIDECSR) ) + if( gpVT_CurTerm->Mode == TERM_MODE_TEXT && !(gpVT_CurTerm->Flags & VT_FLAG_HIDECSR) ) { tVideo_IOCtl_Pos pos; pos.x = gpVT_CurTerm->WritePos % gpVT_CurTerm->Width; @@ -670,41 +699,6 @@ void VT_KBCallBack(Uint32 Codepoint) } } -/** - * \fn void VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count) - * \brief Print a string to the Virtual Terminal - */ -void VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count) -{ - Uint32 val; - int i; - for( i = 0; i < Count; i++ ) - { - if( Buffer[i] == 0x1B ) // Escape Sequence - { - i ++; - i += VT_int_ParseEscape(Term, (char*)&Buffer[i]); - continue; - } - - if( Buffer[i] < 128 ) // Plain ASCII - VT_int_PutChar(Term, Buffer[i]); - else { // UTF-8 - i += ReadUTF8(&Buffer[i], &val); - VT_int_PutChar(Term, val); - } - } - - // Update cursor - if( Term == gpVT_CurTerm && !(Term->Flags & VT_FLAG_HIDECSR) ) - { - tVideo_IOCtl_Pos pos; - pos.x = Term->WritePos % Term->Width; - pos.y = Term->WritePos / Term->Width; - VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETCURSOR, &pos); - } -} - /** * \fn void VT_int_ClearLine(tVTerm *Term, int Num) * \brief Clears a line in a virtual terminal @@ -833,6 +827,43 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer) return j + 1; } +/** + * \fn void VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count) + * \brief Print a string to the Virtual Terminal + */ +void VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count) +{ + Uint32 val; + int i; + for( i = 0; i < Count; i++ ) + { + if( Buffer[i] == 0x1B ) // Escape Sequence + { + i ++; + i += VT_int_ParseEscape(Term, (char*)&Buffer[i]); + continue; + } + + if( Buffer[i] < 128 ) // Plain ASCII + VT_int_PutChar(Term, Buffer[i]); + else { // UTF-8 + i += ReadUTF8(&Buffer[i], &val); + VT_int_PutChar(Term, val); + } + } + // Update Screen + VT_int_UpdateScreen( Term, 0 ); + + // Update cursor + if( Term == gpVT_CurTerm && !(Term->Flags & VT_FLAG_HIDECSR) ) + { + tVideo_IOCtl_Pos pos; + pos.x = Term->WritePos % Term->Width; + pos.y = Term->WritePos / Term->Width; + VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETCURSOR, &pos); + } +} + /** * \fn void VT_int_PutChar(tVTerm *Term, Uint32 Ch) * \brief Write a single character to a VTerm @@ -847,6 +878,7 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch) { case '\0': return; // Ignore NULL byte case '\n': + VT_int_UpdateScreen( Term, 0 ); // Update the line before newlining Term->WritePos += Term->Width; case '\r': Term->WritePos -= Term->WritePos % Term->Width; @@ -921,14 +953,12 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch) //LOG("Scrolled buffer"); VT_int_UpdateScreen( Term, 1 ); } - else if(Term->WritePos > Term->Width*Term->Height+Term->ViewPos) + else if(Term->WritePos >= Term->Width*Term->Height+Term->ViewPos) { Term->ViewPos += Term->Width; //LOG("Scrolled screen"); VT_int_UpdateScreen( Term, 1 ); } - else - VT_int_UpdateScreen( Term, 0 ); //LEAVE('-'); } @@ -940,10 +970,11 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch) void VT_int_UpdateScreen( tVTerm *Term, int UpdateAll ) { // Only update if this is the current terminal - if( Term != &gVT_Terminals[giVT_CurrentTerminal] ) return; + if( Term != gpVT_CurTerm ) return; - if( Term->Mode == TERM_MODE_TEXT ) + switch( Term->Mode ) { + case TERM_MODE_TEXT: if(UpdateAll) { //LOG("UpdateAll = 1"); //LOG("VFS_WriteAt(0x%x, 0, %i*sizeof(tVT_Char), &Term->Text[%i])", @@ -966,15 +997,15 @@ void VT_int_UpdateScreen( tVTerm *Term, int UpdateAll ) &Term->Text[pos] ); } - } - else - { + break; + case TERM_MODE_FB: VFS_WriteAt( giVT_OutputDevHandle, 0, Term->Width*Term->Height*sizeof(Uint32), - &Term->Buffer + Term->Buffer ); + break; } } @@ -987,14 +1018,19 @@ void VT_int_ChangeMode(tVTerm *Term, int NewMode) switch(NewMode) { case TERM_MODE_TEXT: + Log_Log("VTerm", "Set VT %p to text mode", Term); free(Term->Buffer); Term->Text = calloc( Term->Width*Term->Height*VT_SCROLLBACK, sizeof(tVT_Char) ); break; case TERM_MODE_FB: + Log_Log("VTerm", "Set VT %p to framebuffer mode (%ix%i)", Term, + Term->Width, Term->Height); free(Term->Text); Term->Buffer = calloc( Term->Width*Term->Height, sizeof(Uint32) ); + Log_Debug("VTerm", "Term->Buffer = %p", Term->Buffer); break; - //case TERM_MODE_OPENGL: + //case TERM_MODE_2DACCEL: + //case TERM_MODE_3DACCEL: // return; }