#define DEFAULT_INPUT "Keyboard"
#define DEFAULT_WIDTH 640
#define DEFAULT_HEIGHT 480
-#define DEFAULT_SCROLLBACK 2 // 2 Screens of text + current screen
+#define DEFAULT_SCROLLBACK 4 // 2 Screens of text + current screen
//#define DEFAULT_SCROLLBACK 0
// === TYPES ===
// === PROTOTYPES ===
int VT_Install(char **Arguments);
-char *VT_ReadDir(tVFS_Node *Node, int Pos);
-tVFS_Node *VT_FindDir(tVFS_Node *Node, const char *Name);
+ int VT_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
+tVFS_Node *VT_FindDir(tVFS_Node *Node, const char *Name, Uint Flags);
int VT_Root_IOCtl(tVFS_Node *Node, int Id, void *Data);
-size_t VT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
-size_t VT_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);
+size_t VT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags);
+size_t VT_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags);
int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data);
+void VT_Terminal_Reference(tVFS_Node *Node);
+void VT_Terminal_Close(tVFS_Node *Node);
+//void VT_SetTerminal(int Term);
// === CONSTANTS ===
if( strcmp(opt, "Video") == 0 ) {
if( !gsVT_OutputDevice )
- gsVT_OutputDevice = strdup(val);
+ gsVT_OutputDevice = val;
}
else if( strcmp(opt, "Input") == 0 ) {
if( !gsVT_InputDevice )
- gsVT_InputDevice = strdup(val);
+ gsVT_InputDevice = val;
}
else if( strcmp(opt, "Width") == 0 ) {
giVT_RealWidth = atoi( val );
else if( strcmp(opt, "Scrollback") == 0 ) {
giVT_Scrollback = atoi( val );
}
+ else {
+ Log_Notice("VTerm", "Unknown option '%s'", opt);
+ }
}
}
VT_InitOutput();
VT_InitInput();
+
// Create Nodes
+ Log_Debug("VTerm", "Initialising nodes (and creating buffers)");
for( i = 0; i < NUM_VTS; i++ )
{
gVT_Terminals[i].Mode = TERM_MODE_TEXT;
DevFS_AddDevice( &gVT_DrvInfo );
// Set kernel output to VT0
+ Log_Debug("VTerm", "Setting kernel output to VT#0");
Debug_SetKTerminal("/Devices/VTerm/0");
return MODULE_ERR_OK;
if( Width != mode.width || Height != mode.height )
{
Log_Warning("VTerm",
- "Selected resolution (%ix%i is not supported) by the device, using (%ix%i)",
+ "Selected resolution (%ix%i) is not supported by the device, using (%ix%i)",
giVT_RealWidth, giVT_RealHeight,
mode.width, mode.height
);
* \fn char *VT_ReadDir(tVFS_Node *Node, int Pos)
* \brief Read from the VTerm Directory
*/
-char *VT_ReadDir(tVFS_Node *Node, int Pos)
+int VT_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
- if(Pos < 0) return NULL;
- if(Pos >= NUM_VTS) return NULL;
- return strdup( gVT_Terminals[Pos].Name );
+ if(Pos < 0) return -EINVAL;
+ if(Pos >= NUM_VTS) return -EINVAL;
+ strncpy(Dest, gVT_Terminals[Pos].Name, FILENAME_MAX);
+ return 0;
}
/**
* \param Node Root node
* \param Name Name (number) of the terminal
*/
-tVFS_Node *VT_FindDir(tVFS_Node *Node, const char *Name)
+tVFS_Node *VT_FindDir(tVFS_Node *Node, const char *Name, Uint Flags)
{
int num;
/**
* \brief Read from a virtual terminal
*/
-size_t VT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
+size_t VT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags)
{
- int pos = 0;
- int avail;
+ int pos, avail, rv;
tVTerm *term = &gVT_Terminals[ Node->Inode ];
Uint32 *codepoint_buf = Buffer;
Uint32 *codepoint_in;
+ tTime timeout_zero = 0;
Mutex_Acquire( &term->ReadingLock );
case TERM_MODE_TEXT:
VT_int_UpdateCursor(term, 1);
- VFS_SelectNode(Node, VFS_SELECT_READ, NULL, "VT_Read (UTF-8)");
+ rv = VFS_SelectNode(Node, VFS_SELECT_READ,
+ (Flags & VFS_IOFLAG_NOBLOCK ? &timeout_zero : NULL), "VT_Read (UTF-8)");
+ if(!rv) {
+ errno = (Flags & VFS_IOFLAG_NOBLOCK) ? EWOULDBLOCK : EINTR;
+ return -1;
+ }
avail = term->InputWrite - term->InputRead;
if(avail < 0)
avail += MAX_INPUT_CHARS8;
- if(avail > Length - pos)
- avail = Length - pos;
+ if(avail > Length)
+ avail = Length;
+ pos = 0;
while( avail -- )
{
((char*)Buffer)[pos] = term->InputBuffer[term->InputRead];
//case TERM_MODE_FB:
// Other - UCS-4
default:
- VFS_SelectNode(Node, VFS_SELECT_READ, NULL, "VT_Read (UCS-4)");
+ rv = VFS_SelectNode(Node, VFS_SELECT_READ,
+ (Flags & VFS_IOFLAG_NOBLOCK ? &timeout_zero : NULL), "VT_Read (UCS-4)");
+ if(!rv) {
+ errno = (Flags & VFS_IOFLAG_NOBLOCK) ? EWOULDBLOCK : EINTR;
+ return -1;
+ }
avail = term->InputWrite - term->InputRead;
if(avail < 0)
avail += MAX_INPUT_CHARS32;
Length /= 4;
- if(avail > Length - pos)
- avail = Length - pos;
+ if(avail > Length)
+ avail = Length;
codepoint_in = (void*)term->InputBuffer;
codepoint_buf = Buffer;
+ pos = 0;
while( avail -- )
{
codepoint_buf[pos] = codepoint_in[term->InputRead];
/**
* \brief Write to a virtual terminal
*/
-size_t VT_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer)
+size_t VT_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags)
{
tVTerm *term = &gVT_Terminals[ Node->Inode ];
int size;
// - Sanity Checking
size = term->Width*term->Height*4;
if( Offset > size ) {
- Log_Notice("VTerm", "VT_Write: Offset (0x%llx) > FBSize (0x%x)",
- Offset, size);
+ Log_Notice("VTerm", "VT_Write: %i Offset (0x%llx) > FBSize (0x%x)",
+ (int)Node->Inode, Offset, size);
return 0;
}
if( Offset + Length > size ) {
break;
}
- return 0;
+ return Length;
}
/**
return -1;
}
+void VT_Terminal_Reference(tVFS_Node *Node)
+{
+ // Append PID to list
+}
+
+void VT_Terminal_Close(tVFS_Node *Node)
+{
+ // Remove PID from list
+}
+
/**
* \fn void VT_SetTerminal(int ID)
* \brief Set the current terminal
gpVT_CurTerm->Buffer = malloc( gpVT_CurTerm->Width*gpVT_CurTerm->Height*4 );
if( gpVT_CurTerm->Width < giVT_RealWidth )
{
- int line;
Uint ofs = 0;
Uint32 *dest = gpVT_CurTerm->Buffer;
// Slower scanline copy
- for( line = 0; line < gpVT_CurTerm->Height; line ++ )
+ for( int line = 0; line < gpVT_CurTerm->Height; line ++ )
{
VFS_ReadAt(giVT_OutputDevHandle, ofs, gpVT_CurTerm->Width*4, dest);
ofs += giVT_RealWidth * 4;
gpVT_CurTerm->Buffer
);
}
+ LOG("Cached screen contents");
}
// Update current terminal ID
giVT_CurrentTerminal = ID;
gpVT_CurTerm = &gVT_Terminals[ID];
+ LOG("Attempting VT_SetMode");
+
if( gpVT_CurTerm->Mode == TERM_MODE_TEXT )
{
VT_SetMode( VIDEO_BUFFMT_TEXT );
VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETCURSORBITMAP, gpVT_CurTerm->VideoCursor);
VT_SetMode( VIDEO_BUFFMT_FRAMEBUFFER );
}
-
+
+ LOG("Mode set");
+
if(gpVT_CurTerm->Buffer)
{
// TODO: Handle non equal sized
gpVT_CurTerm->Width*gpVT_CurTerm->Height*sizeof(Uint32),
gpVT_CurTerm->Buffer
);
+ LOG("Updated screen contents");
}
VT_int_UpdateCursor(gpVT_CurTerm, 1);
// Update the screen
VT_int_UpdateScreen(gpVT_CurTerm, 1);
+ LOG("done");
}