Usermode/libc - Fix strchr and strrchr behavior
[tpg/acess2.git] / Kernel / drv / vterm.c
diff --git a/Kernel/drv/vterm.c b/Kernel/drv/vterm.c
deleted file mode 100644 (file)
index 71c4d4a..0000000
+++ /dev/null
@@ -1,767 +0,0 @@
-/*
- * Acess2 Virtual Terminal Driver
- */
-#define DEBUG  0
-#include "vterm.h"
-#include <fs_devfs.h>
-#include <modules.h>
-#include <api_drv_keyboard.h>
-#include <api_drv_video.h>
-#include <errno.h>
-#include <semaphore.h>
-
-// === CONSTANTS ===
-#define VERSION        ((0<<8)|(50))
-
-#define        NUM_VTS 8
-//#define DEFAULT_OUTPUT       "BochsGA"
-#define DEFAULT_OUTPUT "Vesa"
-#define FALLBACK_OUTPUT        "x86_VGAText"
-#define DEFAULT_INPUT  "PS2Keyboard"
-#define        DEFAULT_WIDTH   640
-#define        DEFAULT_HEIGHT  480
-#define DEFAULT_SCROLLBACK     2       // 2 Screens of text + current screen
-//#define DEFAULT_SCROLLBACK   0
-
-// === TYPES ===
-
-// === IMPORTS ===
-extern void    Debug_SetKTerminal(const char *File);
-
-// === 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_Root_IOCtl(tVFS_Node *Node, int Id, void *Data);
-Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
-Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer);
- int   VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data);
-
-// === CONSTANTS ===
-
-// === GLOBALS ===
-MODULE_DEFINE(0, VERSION, VTerm, VT_Install, NULL, NULL);
-tVFS_NodeType  gVT_RootNodeType = {
-       .TypeName = "VTerm Root",
-       .ReadDir = VT_ReadDir,
-       .FindDir = VT_FindDir,
-       .IOCtl = VT_Root_IOCtl
-       };
-tVFS_NodeType  gVT_TermNodeType = {
-       .TypeName = "VTerm",
-       .Read = VT_Read,
-       .Write = VT_Write,
-       .IOCtl = VT_Terminal_IOCtl
-       };
-tDevFS_Driver  gVT_DrvInfo = {
-       NULL, "VTerm",
-       {
-       .Flags = VFS_FFLAG_DIRECTORY,
-       .Size = NUM_VTS,
-       .Inode = -1,
-       .NumACLs = 0,
-       .Type = &gVT_RootNodeType
-       }
-};
-// --- Terminals ---
-tVTerm gVT_Terminals[NUM_VTS];
- int   giVT_CurrentTerminal = 0;
-tVTerm *gpVT_CurTerm = &gVT_Terminals[0];
-// --- Video State ---
-short  giVT_RealWidth  = DEFAULT_WIDTH;        //!< Screen Width
-short  giVT_RealHeight = DEFAULT_HEIGHT;       //!< Screen Height
- int   giVT_Scrollback = DEFAULT_SCROLLBACK;
-// --- Driver Handles ---
-char   *gsVT_OutputDevice = NULL;
-char   *gsVT_InputDevice = NULL;
- int   giVT_OutputDevHandle = -2;
- int   giVT_InputDevHandle = -2;
-
-// === CODE ===
-/**
- * \fn int VT_Install(char **Arguments)
- * \brief Installs the Virtual Terminal Driver
- */
-int VT_Install(char **Arguments)
-{
-        int    i;
-       
-       // Scan Arguments
-       if(Arguments)
-       {
-               char    **args;
-               const char      *arg;
-               for(args = Arguments; (arg = *args); args++ )
-               {
-                       char    data[strlen(arg)+1];
-                       char    *opt = data;
-                       char    *val;
-                       
-                       val = strchr(arg, '=');
-                       strcpy(data, arg);
-                       if( val ) {
-                               data[ val - arg ] = '\0';
-                               val ++;
-                       }
-                       Log_Debug("VTerm", "Argument '%s'", arg);
-                       
-                       if( strcmp(opt, "Video") == 0 ) {
-                               if( !gsVT_OutputDevice )
-                                       gsVT_OutputDevice = strdup(val);
-                       }
-                       else if( strcmp(opt, "Input") == 0 ) {
-                               if( !gsVT_InputDevice )
-                                       gsVT_InputDevice = strdup(val);
-                       }
-                       else if( strcmp(opt, "Width") == 0 ) {
-                               giVT_RealWidth = atoi( val );
-                       }
-                       else if( strcmp(opt, "Height") == 0 ) {
-                               giVT_RealHeight = atoi( val );
-                       }
-                       else if( strcmp(opt, "Scrollback") == 0 ) {
-                               giVT_Scrollback = atoi( val );
-                       }
-               }
-       }
-       
-       // Apply Defaults
-       if(!gsVT_OutputDevice)  gsVT_OutputDevice = (char*)DEFAULT_OUTPUT;
-       else if( Module_EnsureLoaded( gsVT_OutputDevice ) )     gsVT_OutputDevice = (char*)DEFAULT_OUTPUT;
-       if( Module_EnsureLoaded( gsVT_OutputDevice ) )  gsVT_OutputDevice = (char*)FALLBACK_OUTPUT;
-       if( Module_EnsureLoaded( gsVT_OutputDevice ) ) {
-               Log_Error("VTerm", "Fallback video '%s' is not avaliable, giving up", FALLBACK_OUTPUT);
-               return MODULE_ERR_MISC;
-       }
-       
-       if(!gsVT_InputDevice)   gsVT_InputDevice = (char*)DEFAULT_INPUT;
-       else if( Module_EnsureLoaded( gsVT_InputDevice ) )      gsVT_InputDevice = (char*)DEFAULT_INPUT;
-       if( Module_EnsureLoaded( gsVT_OutputDevice ) ) {
-               Log_Error("VTerm", "Fallback input '%s' is not avaliable, input will not be avaliable", DEFAULT_INPUT);
-       }
-       
-       // Create device 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);
-       
-       VT_InitOutput();
-       VT_InitInput();
-       
-       // Create Nodes
-       for( i = 0; i < NUM_VTS; i++ )
-       {
-               gVT_Terminals[i].Mode = TERM_MODE_TEXT;
-               gVT_Terminals[i].Flags = 0;
-//             gVT_Terminals[i].Flags = VT_FLAG_HIDECSR;       //HACK - Stop all those memcpy calls
-               gVT_Terminals[i].CurColour = DEFAULT_COLOUR;
-               gVT_Terminals[i].WritePos = 0;
-               gVT_Terminals[i].AltWritePos = 0;
-               gVT_Terminals[i].ViewPos = 0;
-               gVT_Terminals[i].ReadingThread = -1;
-               gVT_Terminals[i].ScrollHeight = 0;
-               
-               // 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';
-               gVT_Terminals[i].Node.Inode = i;
-               gVT_Terminals[i].Node.ImplPtr = &gVT_Terminals[i];
-               gVT_Terminals[i].Node.NumACLs = 0;      // Only root can open virtual terminals
-       
-               gVT_Terminals[i].Node.Type = &gVT_TermNodeType; 
-//             Semaphore_Init(&gVT_Terminals[i].InputSemaphore, 0, MAX_INPUT_CHARS8, "VTerm", gVT_Terminals[i].Name);
-       }
-       
-       // Add to DevFS
-       DevFS_AddDevice( &gVT_DrvInfo );
-       
-       // Set kernel output to VT0
-       Debug_SetKTerminal("/Devices/VTerm/0");
-       
-       return MODULE_ERR_OK;
-}
-
-/**
- * \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
-                       );
-               giVT_RealWidth = mode.width;
-               giVT_RealHeight = mode.height;
-       }
-       VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_GETSETMODE, &tmp );
-       
-       // Resize text terminals if needed
-       if( gVT_Terminals[0].Text && (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
-               Log_Debug("VTerm", "Resizing terminals to %ix%i",
-                       giVT_RealWidth/giVT_CharWidth, giVT_RealHeight/giVT_CharHeight);
-               for( i = 0; i < NUM_VTS; i ++ )
-               {
-                       if( gVT_Terminals[i].Mode != TERM_MODE_TEXT )   continue;
-                       
-                       gVT_Terminals[i].TextWidth = giVT_RealWidth/giVT_CharWidth;
-                       gVT_Terminals[i].TextHeight = giVT_RealHeight/giVT_CharHeight;
-                       gVT_Terminals[i].ScrollHeight = gVT_Terminals[i].TextHeight;
-                       
-                       gVT_Terminals[i].Text = realloc(
-                               gVT_Terminals[i].Text,
-                               newBufSize*sizeof(tVT_Char)
-                               );
-               }
-       }
-}
-
-/**
- * \fn char *VT_ReadDir(tVFS_Node *Node, int Pos)
- * \brief Read from the VTerm Directory
- */
-char *VT_ReadDir(tVFS_Node *Node, int Pos)
-{
-       if(Pos < 0)     return NULL;
-       if(Pos >= NUM_VTS)      return NULL;
-       return strdup( gVT_Terminals[Pos].Name );
-}
-
-/**
- * \fn tVFS_Node *VT_FindDir(tVFS_Node *Node, const 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, const char *Name)
-{
-        int    num;
-       
-       ENTER("pNode sName", Node, Name);
-       
-       // Open the input and output files if needed
-       if(giVT_OutputDevHandle == -2)  VT_InitOutput();
-       if(giVT_InputDevHandle == -2)   VT_InitInput();
-       
-       // Sanity check name
-       if(Name[0] < '0' || Name[0] > '9' || Name[1] != '\0') {
-               LEAVE('n');
-               return NULL;
-       }
-       // Get index
-       num = Name[0] - '0';
-       if(num >= NUM_VTS) {
-               LEAVE('n');
-               return NULL;
-       }
-       // Return node
-       LEAVE('p', &gVT_Terminals[num].Node);
-       return &gVT_Terminals[num].Node;
-}
-
-/**
- * \fn int VT_Root_IOCtl(tVFS_Node *Node, int Id, void *Data)
- * \brief Control the VTerm Driver
- */
-int VT_Root_IOCtl(tVFS_Node *Node, int Id, void *Data)
-{
-        int    len;
-       switch(Id)
-       {
-       case DRV_IOCTL_TYPE:    return DRV_TYPE_MISC;
-       case DRV_IOCTL_IDENT:   memcpy(Data, "VT\0\0", 4);      return 0;
-       case DRV_IOCTL_VERSION: return VERSION;
-       case DRV_IOCTL_LOOKUP:  return 0;
-       
-       case 4: // Get Video Driver
-               if(Data)        strcpy(Data, gsVT_OutputDevice);
-               return strlen(gsVT_OutputDevice);
-       
-       case 5: // Set Video Driver
-               if(!Data)       return -EINVAL;
-               if(Threads_GetUID() != 0)       return -EACCES;
-               
-               len = strlen(Data);
-               
-               // TODO: Check if the string used is a heap string
-               
-               free(gsVT_OutputDevice);
-               
-               gsVT_OutputDevice = malloc(len+1);
-               strcpy(gsVT_OutputDevice, Data);
-               
-               VFS_Close(giVT_OutputDevHandle);
-               giVT_OutputDevHandle = -1;
-               
-               VT_InitOutput();
-               return 1;
-       }
-       return 0;
-}
-
-/**
- * \brief Read from a virtual terminal
- */
-Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
-{
-        int    pos = 0;
-        int    avail;
-       tVTerm  *term = &gVT_Terminals[ Node->Inode ];
-       Uint32  *codepoint_buf = Buffer;
-       Uint32  *codepoint_in;
-       
-       Mutex_Acquire( &term->ReadingLock );
-       
-       // Check current mode
-       switch(term->Mode)
-       {
-       // Text Mode (UTF-8)
-       case TERM_MODE_TEXT:
-               VT_int_UpdateCursor(term, 1);
-       
-               VFS_SelectNode(Node, VFS_SELECT_READ, NULL, "VT_Read (UTF-8)");
-               
-               avail = term->InputWrite - term->InputRead;
-               if(avail < 0)
-                       avail += MAX_INPUT_CHARS8;
-               if(avail > Length - pos)
-                       avail = Length - pos;
-               
-               while( avail -- )
-               {
-                       ((char*)Buffer)[pos] = term->InputBuffer[term->InputRead];
-                       pos ++;
-                       term->InputRead ++;
-                       while(term->InputRead >= MAX_INPUT_CHARS8)
-                               term->InputRead -= MAX_INPUT_CHARS8;
-               }
-               break;
-       
-       //case TERM_MODE_FB:
-       // Other - UCS-4
-       default:
-               VFS_SelectNode(Node, VFS_SELECT_READ, NULL, "VT_Read (UCS-4)");
-               
-               avail = term->InputWrite - term->InputRead;
-               if(avail < 0)
-                       avail += MAX_INPUT_CHARS32;
-               Length /= 4;
-               if(avail > Length - pos)
-                       avail = Length - pos;
-               
-               codepoint_in = (void*)term->InputBuffer;
-               codepoint_buf = Buffer;
-               
-               while( avail -- )
-               {
-                       codepoint_buf[pos] = codepoint_in[term->InputRead];
-                       pos ++;
-                       term->InputRead ++;
-                       while(term->InputRead >= MAX_INPUT_CHARS32)
-                               term->InputRead -= MAX_INPUT_CHARS32;
-               }
-               pos *= 4;
-               break;
-       }
-       
-       // Mark none avaliable if buffer empty
-       if( term->InputRead == term->InputWrite )
-               VFS_MarkAvaliable(&term->Node, 0);
-       
-       term->ReadingThread = -1;
-
-//     VT_int_UpdateCursor(term, term->Mode == TERM_MODE_TEXT);
-
-       Mutex_Release( &term->ReadingLock );
-       
-       return pos;
-}
-
-/**
- * \fn Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer)
- * \brief Write to a virtual terminal
- */
-Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer)
-{
-       tVTerm  *term = &gVT_Terminals[ Node->Inode ];
-        int    size;
-       
-       // 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;
-               }
-               
-               // 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 );
-               }
-               break;
-       }
-       
-       return 0;
-}
-
-/**
- * \fn int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data)
- * \brief Call an IO Control on a virtual terminal
- */
-int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data)
-{
-        int    *iData = Data;
-        int    ret;
-       tVTerm  *term = Node->ImplPtr;
-       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;
-       }
-       
-       switch(Id)
-       {
-       // --- Core Defined
-       case DRV_IOCTL_TYPE:
-               LEAVE('i', DRV_TYPE_TERMINAL);
-               return DRV_TYPE_TERMINAL;
-       case DRV_IOCTL_IDENT:
-               memcpy(Data, "VT\0\0", 4);
-               LEAVE('i', 0);
-               return 0;
-       case DRV_IOCTL_VERSION:
-               LEAVE('x', VERSION);
-               return VERSION;
-       case DRV_IOCTL_LOOKUP:
-               LEAVE('i', 0);
-               return 0;
-       
-       // Get/Set the mode (and apply any changes)
-       case TERM_IOCTL_MODETYPE:
-               if(Data != NULL)
-               {
-                       if( CheckMem(Data, sizeof(int)) == 0 ) {
-                               LEAVE('i', -1);
-                               return -1;
-                       }
-                       Log_Log("VTerm", "VTerm %i mode set to %i", (int)Node->Inode, *iData);
-                       
-                       // Update mode if needed
-                       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)
-                               VT_SetTerminal( giVT_CurrentTerminal );
-               }
-               LEAVE('i', term->Mode);
-               return term->Mode;
-       
-       // Get/set the terminal width
-       case TERM_IOCTL_WIDTH:
-               if(Data != NULL) {
-                       if( CheckMem(Data, sizeof(int)) == 0 ) {
-                               LEAVE('i', -1);
-                               return -1;
-                       }
-                       term->NewWidth = *iData;
-               }
-               if( term->NewWidth )
-                       ret = term->NewWidth;
-               else if( term->Mode == TERM_MODE_TEXT )
-                       ret = term->TextWidth;
-               else
-                       ret = term->Width;
-               LEAVE('i', ret);
-               return ret;
-       
-       // Get/set the terminal height
-       case TERM_IOCTL_HEIGHT:
-               if(Data != NULL) {
-                       if( CheckMem(Data, sizeof(int)) == 0 ) {
-                               LEAVE('i', -1);
-                               return -1;
-                       }
-                       term->NewHeight = *iData;
-               }
-               if( term->NewHeight )
-                       ret = term->NewHeight;
-               else if( term->Mode == TERM_MODE_TEXT )
-                       ret = term->TextHeight;
-               else
-                       ret = term->Height;
-               LEAVE('i', ret);
-               return ret;
-       
-       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;
-       
-       case TERM_IOCTL_GETSETCURSOR:
-               if(Data != NULL)
-               {
-                       tVideo_IOCtl_Pos        *pos = Data;
-                       if( !CheckMem(Data, sizeof(*pos)) ) {
-                               errno = -EINVAL;
-                               LEAVE('i', -1);
-                               return -1;
-                       }
-               
-                       if( term->Mode == TERM_MODE_TEXT )
-                       {
-                               if(term->Flags & VT_FLAG_ALTBUF)
-                                       term->AltWritePos = pos->x + pos->y * term->TextWidth;
-                               else
-                                       term->WritePos = pos->x + pos->y * term->TextWidth + term->ViewPos;
-                               VT_int_UpdateCursor(term, 0);
-                       }
-                       else
-                       {
-                               term->VideoCursorX = pos->x;
-                               term->VideoCursorY = pos->y;
-                               VT_int_UpdateCursor(term, 1);
-                       }
-               }
-               ret = (term->Flags & VT_FLAG_ALTBUF) ? term->AltWritePos : term->WritePos-term->ViewPos;
-               LEAVE('i', ret);
-               return ret;
-
-       case TERM_IOCTL_SETCURSORBITMAP: {
-               tVideo_IOCtl_Bitmap     *bmp = Data;
-               if( Data == NULL )
-               {
-                       free( term->VideoCursor );
-                       term->VideoCursor = NULL;
-                       LEAVE('i', 0);
-                       return 0;
-               }
-
-               // Sanity check bitmap
-               if( !CheckMem(bmp, sizeof(tVideo_IOCtl_Bitmap)) ) {
-                       Log_Notice("VTerm", "%p in TERM_IOCTL_SETCURSORBITMAP invalid", bmp);
-                       errno = -EINVAL;
-                       LEAVE_RET('i', -1);
-               }
-               if( !CheckMem(bmp->Data, bmp->W*bmp->H*sizeof(Uint32)) ) {
-                       Log_Notice("VTerm", "%p in TERM_IOCTL_SETCURSORBITMAP invalid", bmp);
-                       errno = -EINVAL;
-                       LEAVE_RET('i', -1);
-               }
-
-               // Reallocate if needed
-               if(term->VideoCursor)
-               {
-                       if(bmp->W * bmp->H != term->VideoCursor->W * term->VideoCursor->H) {
-                               free(term->VideoCursor);
-                               term->VideoCursor = NULL;
-                       }
-               }
-               if(!term->VideoCursor) {
-                       term->VideoCursor = malloc(sizeof(tVideo_IOCtl_Pos) + bmp->W*bmp->H*sizeof(Uint32));
-                       if(!term->VideoCursor) {
-                               Log_Error("VTerm", "Unable to allocate memory for cursor");
-                               errno = -ENOMEM;
-                               LEAVE_RET('i', -1);
-                       }
-               }
-               
-               memcpy(term->VideoCursor, bmp, sizeof(tVideo_IOCtl_Pos) + bmp->W*bmp->H*sizeof(Uint32));
-       
-               Log_Debug("VTerm", "Set VT%i's cursor to %p %ix%i",
-                       (int)term->Node.Inode, bmp, bmp->W, bmp->H);
-
-               if(gpVT_CurTerm == term)
-                       VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETCURSORBITMAP, term->VideoCursor);
-       
-               LEAVE('i', 0);
-               return 0; }
-       }
-       LEAVE('i', -1);
-       return -1;
-}
-
-/**
- * \fn void VT_SetTerminal(int ID)
- * \brief Set the current terminal
- */
-void VT_SetTerminal(int ID)
-{
-       // Copy the screen state
-       if( ID != giVT_CurrentTerminal && gpVT_CurTerm->Mode != TERM_MODE_TEXT )
-       {
-               if( !gpVT_CurTerm->Buffer )
-                       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 ++ )
-                       {
-                               VFS_ReadAt(giVT_OutputDevHandle, ofs, gpVT_CurTerm->Width*4, dest);
-                               ofs += giVT_RealWidth * 4;
-                               dest += gpVT_CurTerm->Width;
-                       }
-               }
-               else
-               {
-                       VFS_ReadAt(giVT_OutputDevHandle,
-                               0, gpVT_CurTerm->Height*giVT_RealWidth*4,
-                               gpVT_CurTerm->Buffer
-                               );
-               }
-       }
-
-       // Update current terminal ID
-       Log_Log("VTerm", "Changed terminal from %i to %i", giVT_CurrentTerminal, ID);
-       giVT_CurrentTerminal = ID;
-       gpVT_CurTerm = &gVT_Terminals[ID];
-       
-       if( gpVT_CurTerm->Mode == TERM_MODE_TEXT )
-       {
-               VT_SetMode( VIDEO_BUFFMT_TEXT );
-       }
-       else
-       {
-               // Update the cursor image
-               if(gpVT_CurTerm->VideoCursor)
-                       VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETCURSORBITMAP, gpVT_CurTerm->VideoCursor);
-               VT_SetMode( VIDEO_BUFFMT_FRAMEBUFFER );
-       }
-       
-       if(gpVT_CurTerm->Buffer)
-       {
-               // TODO: Handle non equal sized
-               VFS_WriteAt(
-                       giVT_OutputDevHandle,
-                       0,
-                       gpVT_CurTerm->Width*gpVT_CurTerm->Height*sizeof(Uint32),
-                       gpVT_CurTerm->Buffer
-                       );
-       }
-       
-       VT_int_UpdateCursor(gpVT_CurTerm, 1);
-       // Update the screen
-       VT_int_UpdateScreen(gpVT_CurTerm, 1);
-}

UCC git Repository :: git.ucc.asn.au