X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fdrv%2Fvterm.c;h=094903cda16cccff4005c6fca8cad5d50231df32;hb=8be652c8915e16cd64b0b34c84ca43d9f892ded9;hp=b7e7a8b21a8d33f4bd56a0a9cbad45a6b357f9aa;hpb=e674fe41b89e98285db30fc747771446acb276e3;p=tpg%2Facess2.git diff --git a/Kernel/drv/vterm.c b/Kernel/drv/vterm.c index b7e7a8b2..094903cd 100644 --- a/Kernel/drv/vterm.c +++ b/Kernel/drv/vterm.c @@ -39,6 +39,10 @@ enum eVT_InModes { typedef struct { int Mode; //!< Current Mode (see ::eTplTerminal_Modes) int Flags; //!< Flags (see VT_FLAG_*) + + + short NewWidth; //!< Un-applied dimensions (Width) + short NewHeight; //!< Un-applied dimensions (Height) short Width; //!< Virtual Width short Height; //!< Virtual Height short TextWidth; //!< Text Virtual Width @@ -81,8 +85,7 @@ void VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count); void VT_int_PutChar(tVTerm *Term, Uint32 Ch); void VT_int_ScrollFramebuffer( tVTerm *Term ); void VT_int_UpdateScreen( tVTerm *Term, int UpdateAll ); -void VT_int_ChangeMode(tVTerm *Term, int NewMode); -void VT_int_UpdateResolution(tVTerm *Term, int NewWidth, int NewHeight); +void VT_int_ChangeMode(tVTerm *Term, int NewMode, int NewWidth, int NewHeight); // === CONSTANTS === const Uint16 caVT100Colours[] = { @@ -145,12 +148,10 @@ int VT_Install(char **Arguments) val = arg + strpos(arg, '='); *val++ = '\0'; if( strcmp(opt, "Video") == 0 ) { - if(gsVT_OutputDevice) free(gsVT_OutputDevice); - gsVT_OutputDevice = strdup(val); + gsVT_OutputDevice = val; } else if( strcmp(opt, "Input") == 0 ) { - if(gsVT_InputDevice) free(gsVT_InputDevice); - gsVT_InputDevice = strdup(val); + gsVT_InputDevice = val; } else if( strcmp(opt, "Width") == 0 ) { giVT_RealWidth = atoi( val ); @@ -164,9 +165,25 @@ int VT_Install(char **Arguments) } } + if(gsVT_OutputDevice) Modules_InitialiseBuiltin( gsVT_OutputDevice ); + if(gsVT_InputDevice) Modules_InitialiseBuiltin( gsVT_InputDevice ); + // Apply Defaults - if(!gsVT_OutputDevice) gsVT_OutputDevice = "/Devices/"DEFAULT_OUTPUT; - if(!gsVT_InputDevice) gsVT_InputDevice = "/Devices/"DEFAULT_INPUT; + if(!gsVT_OutputDevice) gsVT_OutputDevice = DEFAULT_OUTPUT; + if(!gsVT_InputDevice) gsVT_InputDevice = DEFAULT_INPUT; + + // Create paths + { + char *tmp; + tmp = malloc( 9 + strlen(gsVT_OutputDevice) + 1 ); + strcpy(tmp, "/Devices/"); + strcpy(&tmp[9], gsVT_OutputDevice); + gsVT_OutputDevice = tmp; + tmp = malloc( 9 + strlen(gsVT_InputDevice) + 1 ); + strcpy(tmp, "/Devices/"); + strcpy(&tmp[9], gsVT_InputDevice); + gsVT_InputDevice = tmp; + } Log_Log("VTerm", "Using '%s' as output", gsVT_OutputDevice); Log_Log("VTerm", "Using '%s' as input", gsVT_InputDevice); @@ -180,7 +197,9 @@ int VT_Install(char **Arguments) gVT_Terminals[i].WritePos = 0; gVT_Terminals[i].ViewPos = 0; - VT_int_UpdateResolution( &gVT_Terminals[i], giVT_RealWidth, giVT_RealHeight ); + // Initialise + VT_int_ChangeMode( &gVT_Terminals[i], + TERM_MODE_TEXT, giVT_RealWidth, giVT_RealHeight ); gVT_Terminals[i].Name[0] = '0'+i; gVT_Terminals[i].Name[1] = '\0'; @@ -217,7 +236,7 @@ void VT_InitOutput() Log_Warning("VTerm", "Oh F**k, I can't open the video device '%s'", gsVT_OutputDevice); return ; } - VT_SetResolution(giVT_RealWidth, giVT_RealHeight); + VT_SetResolution( giVT_RealWidth, giVT_RealHeight ); VT_SetTerminal( 0 ); VT_SetMode( VIDEO_BUFFMT_TEXT ); } @@ -233,6 +252,66 @@ void VT_InitInput() VFS_IOCtl(giVT_InputDevHandle, KB_IOCTL_SETCALLBACK, VT_KBCallBack); } +/** + * \brief Set the video resolution + * \param Width New screen width + * \param Height New screen height + */ +void VT_SetResolution(int Width, int Height) +{ + tVideo_IOCtl_Mode mode = {0}; + int tmp; + int i; + + // Create the video mode + mode.width = Width; + mode.height = Height; + mode.bpp = 32; + mode.flags = 0; + + // Set video mode + VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_FINDMODE, &mode ); + tmp = mode.id; + if( Width != mode.width || Height != mode.height ) + { + Log_Warning("VTerm", + "Selected resolution (%ix%i is not supported) by the device, using (%ix%i)", + giVT_RealWidth, giVT_RealHeight, + mode.width, mode.height + ); + } + VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_GETSETMODE, &tmp ); + + // Resize text terminals if needed + if( giVT_RealWidth != mode.width || giVT_RealHeight != mode.height ) + { + int newBufSize = (giVT_RealWidth/giVT_CharWidth) + *(giVT_RealHeight/giVT_CharHeight) + *(giVT_Scrollback+1); + //tVT_Char *tmp; + // Resize the text terminals + giVT_RealWidth = mode.width; + giVT_RealHeight = mode.height; + for( i = 0; i < NUM_VTS; i ++ ) + { + if( gVT_Terminals[i].Mode != TERM_MODE_TEXT ) continue; + + gVT_Terminals[i].Text = realloc( + gVT_Terminals[i].Text, + newBufSize*sizeof(tVT_Char) + ); + } + } +} + +/** + * \brief Set video output buffer mode + */ +void VT_SetMode(int Mode) +{ + VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &Mode ); +} + /** * \fn char *VT_ReadDir(tVFS_Node *Node, int Pos) * \brief Read from the VTerm Directory @@ -247,6 +326,8 @@ char *VT_ReadDir(tVFS_Node *Node, int Pos) /** * \fn tVFS_Node *VT_FindDir(tVFS_Node *Node, char *Name) * \brief Find an item in the VTerm directory + * \param Node Root node + * \param Name Name (number) of the terminal */ tVFS_Node *VT_FindDir(tVFS_Node *Node, char *Name) { @@ -324,6 +405,7 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) // Check current mode switch(term->Mode) { + // Text Mode (UTF-8) case TERM_MODE_TEXT: while(pos < Length) { @@ -337,6 +419,7 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) break; //case TERM_MODE_FB: + // Other - UCS-4 default: while(pos < Length) { @@ -363,29 +446,36 @@ Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) // Write switch( term->Mode ) { + // Print Text case TERM_MODE_TEXT: VT_int_PutString(term, Buffer, Length); break; + // Framebuffer :) case TERM_MODE_FB: + + // - Sanity Checking 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; } + // Copy to the local cache memcpy( (void*)((Uint)term->Buffer + (Uint)Offset), Buffer, Length ); + // Update screen if needed if( Node->Inode == giVT_CurrentTerminal ) { + // Fill entire screen? if( giVT_RealWidth > term->Width || giVT_RealHeight > term->Height ) { + // No? :( Well, just center it int x, y, w, h; x = Offset/4; y = x / term->Width; x %= term->Width; w = Length/4+x; h = w / term->Width; w %= term->Width; @@ -409,6 +499,8 @@ Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) } } // Just pass on (for now) + // TODO: Handle locally too to ensure no information is lost on + // VT Switch (and to isolate terminals from each other) case TERM_MODE_2DACCEL: //case TERM_MODE_3DACCEL: if( Node->Inode == giVT_CurrentTerminal ) @@ -466,8 +558,24 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data) 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); + if( term->Mode != *iData + || term->NewWidth + || term->NewHeight) + { + // Adjust for text mode + if( *iData == TERM_MODE_TEXT ) { + term->NewHeight *= giVT_CharHeight; + term->NewWidth *= giVT_CharWidth; + } + // Fill unchanged dimensions + if(term->NewHeight == 0) term->NewHeight = term->Height; + if(term->NewWidth == 0) term->NewWidth = term->Width; + // Set new mode + VT_int_ChangeMode(term, *iData, term->NewWidth, term->NewHeight); + // Clear unapplied dimensions + term->NewWidth = 0; + term->NewHeight = 0; + } // Update the screen dimensions if(Node->Inode == giVT_CurrentTerminal) @@ -483,14 +591,11 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data) LEAVE('i', -1); return -1; } - if( term->Mode == TERM_MODE_TEXT ) { - VT_int_UpdateResolution(term, *iData * giVT_CharWidth, term->Height); - } - else { - VT_int_UpdateResolution(term, *iData, term->Height); - } + term->NewWidth = *iData; } - if( term->Mode == TERM_MODE_TEXT ) + if( term->NewWidth ) + ret = term->NewWidth; + else if( term->Mode == TERM_MODE_TEXT ) ret = term->TextWidth; else ret = term->Width; @@ -504,14 +609,11 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data) LEAVE('i', -1); return -1; } - if( term->Mode == TERM_MODE_TEXT ) { - VT_int_UpdateResolution(term, term->Width, *iData * giVT_CharWidth); - } - else { - VT_int_UpdateResolution(term, term->Width, *iData); - } + term->NewHeight = *iData; } - if( term->Mode == TERM_MODE_TEXT ) + if( term->NewHeight ) + ret = term->NewHeight; + else if( term->Mode == TERM_MODE_TEXT ) ret = term->TextHeight = *iData; else ret = term->Height; @@ -529,58 +631,6 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data) return -1; } -void VT_SetResolution(int Width, int Height) -{ - tVideo_IOCtl_Mode mode = {0}; - int tmp; - int i; - - // Create the video mode - mode.width = Width; - mode.height = Height; - mode.bpp = 32; - mode.flags = 0; - - // Set video mode - VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_FINDMODE, &mode ); - tmp = mode.id; - if( Width != mode.width || Height != mode.height ) - { - Log_Warning("VTerm", - "Selected resolution (%ix%i is not supported) by the device, using (%ix%i)", - giVT_RealWidth, giVT_RealHeight, - mode.width, mode.height - ); - } - VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_GETSETMODE, &tmp ); - - // Resize text terminals if needed - if( giVT_RealWidth != mode.width || giVT_RealHeight != mode.height ) - { - int newBufSize = (giVT_RealWidth/giVT_CharWidth) - *(giVT_RealHeight/giVT_CharHeight) - *(giVT_Scrollback+1); - //tVT_Char *tmp; - // Resize the text terminals - giVT_RealWidth = mode.width; - giVT_RealHeight = mode.height; - for( i = 0; i < NUM_VTS; i ++ ) - { - if( gVT_Terminals[i].Mode != TERM_MODE_TEXT ) continue; - - gVT_Terminals[i].Text = realloc( - gVT_Terminals[i].Text, - newBufSize*sizeof(tVT_Char) - ); - } - } -} - -void VT_SetMode(int Mode) -{ - VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &Mode ); -} - /** * \fn void VT_SetTerminal(int ID) * \brief Set the current terminal @@ -596,8 +646,8 @@ void VT_SetTerminal(int ID) if( gpVT_CurTerm->Mode == TERM_MODE_TEXT && !(gpVT_CurTerm->Flags & VT_FLAG_HIDECSR) ) { tVideo_IOCtl_Pos pos; - pos.x = gpVT_CurTerm->WritePos % gpVT_CurTerm->TextWidth; - pos.y = gpVT_CurTerm->WritePos / gpVT_CurTerm->TextWidth; + pos.x = (gpVT_CurTerm->WritePos - gpVT_CurTerm->ViewPos) % gpVT_CurTerm->TextWidth; + pos.y = (gpVT_CurTerm->WritePos - gpVT_CurTerm->ViewPos) / gpVT_CurTerm->TextWidth; VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETCURSOR, &pos); } @@ -952,8 +1002,8 @@ void VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count) if( Term == gpVT_CurTerm && !(Term->Flags & VT_FLAG_HIDECSR) ) { tVideo_IOCtl_Pos pos; - pos.x = Term->WritePos % Term->TextWidth; - pos.y = Term->WritePos / Term->TextWidth; + pos.x = (Term->WritePos - Term->ViewPos) % Term->TextWidth; + pos.y = (Term->WritePos - Term->ViewPos) / Term->TextWidth; VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETCURSOR, &pos); } } @@ -1153,29 +1203,13 @@ void VT_int_UpdateScreen( tVTerm *Term, int UpdateAll ) } /** - * \fn void VT_int_ChangeMode(tVTerm *Term, int NewMode) - * \brief Change the mode of a VTerm + * \brief Update the screen mode + * \param Term Terminal to update + * \param NewMode New mode to set + * \param NewWidth New framebuffer width + * \param NewHeight New framebuffer height */ -void VT_int_ChangeMode(tVTerm *Term, int NewMode) -{ - switch(NewMode) - { - case TERM_MODE_TEXT: - Log_Log("VTerm", "Set VT %p to text mode", Term); - break; - case TERM_MODE_FB: - Log_Log("VTerm", "Set VT %p to framebuffer mode (%ix%i)", - Term, Term->Width, Term->Height); - break; - //case TERM_MODE_2DACCEL: - //case TERM_MODE_3DACCEL: - // return; - } - - Term->Mode = NewMode; -} - -void VT_int_UpdateResolution(tVTerm *Term, int NewWidth, int NewHeight) +void VT_int_ChangeMode(tVTerm *Term, int NewMode, int NewWidth, int NewHeight) { int oldW = Term->Width; int oldTW = oldW / giVT_CharWidth; @@ -1194,6 +1228,7 @@ void VT_int_UpdateResolution(tVTerm *Term, int NewWidth, int NewHeight) Term->TextHeight = NewHeight / giVT_CharHeight; Term->Width = NewWidth; Term->Height = NewHeight; + Term->Mode = NewMode; // Allocate new buffers // - Text @@ -1236,6 +1271,23 @@ void VT_int_UpdateResolution(tVTerm *Term, int NewWidth, int NewHeight) ); } } + + + // Debug + switch(NewMode) + { + case TERM_MODE_TEXT: + Log_Log("VTerm", "Set VT %p to text mode (%ix%i)", + Term, Term->TextWidth, Term->TextHeight); + break; + case TERM_MODE_FB: + Log_Log("VTerm", "Set VT %p to framebuffer mode (%ix%i)", + Term, Term->Width, Term->Height); + break; + //case TERM_MODE_2DACCEL: + //case TERM_MODE_3DACCEL: + // return; + } } // ---