+
+ // 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;
+ }
+
+ // Update screen if needed
+ if( Node->Inode == giVT_CurrentTerminal )
+ {
+ if( giVT_RealHeight > term->Height )
+ Offset += (giVT_RealHeight - term->Height) / 2 * term->Width * 4;
+ // Handle undersized virtual terminals
+ if( giVT_RealWidth > term->Width )
+ {
+ // No? :( Well, just center it
+ int x, y, w, h;
+ Uint dst_ofs;
+ // TODO: Fix to handle the final line correctly?
+ x = Offset/4; y = x / term->Width; x %= term->Width;
+ w = Length/4+x; h = w / term->Width; w %= term->Width;
+
+ // Center
+ x += (giVT_RealWidth - term->Width) / 2;
+ dst_ofs = (x + y * giVT_RealWidth) * 4;
+ while(h--)
+ {
+ VFS_WriteAt( giVT_OutputDevHandle,
+ dst_ofs,
+ term->Width * 4,
+ Buffer
+ );
+ Buffer = (void*)( (Uint)Buffer + term->Width*4 );
+ dst_ofs += giVT_RealWidth * 4;
+ }
+ return 0;
+ }
+ else
+ {
+ return VFS_WriteAt( giVT_OutputDevHandle, Offset, Length, Buffer );
+ }
+ }
+ else
+ {
+ if( !term->Buffer )
+ term->Buffer = malloc( term->Width * term->Height * 4 );
+ // Copy to the local cache
+ memcpy( (char*)term->Buffer + (Uint)Offset, Buffer, Length );
+ }
+ break;
+ // 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 )
+ {
+ VFS_Write( giVT_OutputDevHandle, Length, Buffer );
+ }