Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
{
tVTerm *term = &gVT_Terminals[ Node->Inode ];
+ int size;
// Write
switch( term->Mode )
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 );
}
}
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;
}
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);
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;
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;
}
}
-/**
- * \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
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
{
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;
//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('-');
}
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])",
&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;
}
}
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;
}