Added cursor manipulation to vterm & vga
[tpg/acess2.git] / Kernel / drv / vterm.c
index b0684ff..8aa7321 100644 (file)
@@ -5,10 +5,11 @@
 #include <fs_devfs.h>
 #include <modules.h>
 #include <tpl_drv_video.h>
+#include <tpl_drv_keyboard.h>
 
 // === CONSTANTS ===
 #define        NUM_VTS 4
-#define MAX_INPUT_BYTES        64
+#define MAX_INPUT_CHARS        64
 #define VT_SCROLLBACK  4       // 4 Screens of text
 #define DEFAULT_OUTPUT "/Devices/VGA"
 #define DEFAULT_INPUT  "/Devices/PS2Keyboard"
 #define        DEFAULT_HEIGHT  25
 #define        DEFAULT_COLOUR  (VT_COL_BLACK|(VT_COL_WHITE<<16))
 
+#define        VT_FLAG_HIDECSR 0x01
+
 enum eVT_Modes {
-       VT_MODE_TEXT,
-       VT_MODE_8BPP,
-       VT_MODE_16BPP,
-       VT_MODE_24BPP,
-       VT_MODE_32BPP,
+       VT_MODE_TEXT8,  // UTF-8 Text Mode (VT100 Emulation)
+       VT_MODE_TEXT32, // UTF-32 Text Mode (Acess Native)
+       VT_MODE_8BPP,   // 256 Colour Mode
+       VT_MODE_16BPP,  // 16 bit Colour Mode
+       VT_MODE_24BPP,  // 24 bit Colour Mode
+       VT_MODE_32BPP,  // 32 bit Colour Mode
        NUM_VT_MODES
 };
 
 // === TYPES ===
 typedef struct {
         int    Mode;
+        int    Flags;
         int    Width, Height;
         int    ViewPos, WritePos;
        Uint32  CurColour;
        char    Name[2];
-        int    NumInputBytes;
-       Uint8   InputBuffer[MAX_INPUT_BYTES];
+        int    InputRead;
+        int    InputWrite;
+       Uint32  InputBuffer[MAX_INPUT_CHARS];
        union {
                tVT_Char        *Text;
                Uint32          *Buffer;
@@ -48,6 +54,7 @@ tVFS_Node     *VT_FindDir(tVFS_Node *Node, char *Name);
 Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
 Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
  int   VT_IOCtl(tVFS_Node *Node, int Id, void *Data);
+void   VT_KBCallBack(Uint32 Codepoint);
 void   VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count);
  int   VT_int_ParseEscape(tVTerm *Term, char *Buffer);
 void   VT_int_PutChar(tVTerm *Term, Uint32 Ch);
@@ -129,7 +136,8 @@ int VT_Install(char **Arguments)
        // Create Nodes
        for( i = 0; i < NUM_VTS; i++ )
        {
-               gVT_Terminals[i].Mode = VT_MODE_TEXT;
+               gVT_Terminals[i].Mode = VT_MODE_TEXT8;
+               gVT_Terminals[i].Flags = 0;
                gVT_Terminals[i].Width = DEFAULT_WIDTH;
                gVT_Terminals[i].Height = DEFAULT_HEIGHT;
                gVT_Terminals[i].CurColour = DEFAULT_COLOUR;
@@ -173,6 +181,8 @@ void VT_InitInput()
 {
        giVT_InputDevHandle = VFS_Open(gsVT_InputDevice, VFS_OPENFLAG_READ);
        LOG("giVT_InputDevHandle = %x\n", giVT_InputDevHandle);
+       if(giVT_InputDevHandle == -1)   return ;
+       VFS_IOCtl(giVT_InputDevHandle, KB_IOCTL_SETCALLBACK, VT_KBCallBack);
 }
 
 /**
@@ -222,8 +232,38 @@ tVFS_Node *VT_FindDir(tVFS_Node *Node, char *Name)
  */
 Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
 {
-       //ENTER("pNode XOffset XLength pBuffer",  Node, Offset, Length, Buffer);
-       //LEAVE('i', 0);
+        int    pos = 0;
+       tVTerm  *term = &gVT_Terminals[ Node->Inode ];
+       
+       // Check current mode
+       switch(term->Mode)
+       {
+       case VT_MODE_TEXT8:
+               while(pos < Length)
+               {
+                       while(term->InputRead == term->InputWrite)      Proc_Yield();
+                       while(term->InputRead != term->InputWrite)
+                       {
+                               LOG("WriteUTF8(%p, 0x%x)", Buffer+pos, term->InputBuffer[term->InputRead]);
+                               pos += WriteUTF8(Buffer+pos, term->InputBuffer[term->InputRead]);
+                               term->InputRead ++;
+                       }
+               }
+               break;
+       
+       case VT_MODE_TEXT32:
+               while(pos < Length)
+               {
+                       while(term->InputRead == term->InputWrite)      Proc_Yield();
+                       while(term->InputRead != term->InputWrite)
+                       {
+                               ((Uint32*)Buffer)[pos] = term->InputBuffer[term->InputRead];
+                               pos ++;
+                               term->InputRead ++;
+                       }
+               }
+               break;
+       }
        return 0;
 }
 
@@ -240,10 +280,14 @@ Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        // Write
        switch( term->Mode )
        {
-       case VT_MODE_TEXT:
+       case VT_MODE_TEXT8:
                VT_int_PutString(term, Buffer, Length);
                break;
+       case VT_MODE_TEXT32:
+               //VT_int_PutString32(term, Buffer, Length);
+               break;
        }
+       
        //LEAVE('i', 0);
        return 0;
 }
@@ -257,6 +301,23 @@ int VT_IOCtl(tVFS_Node *Node, int Id, void *Data)
        return 0;
 }
 
+/**
+ * \fn void VT_KBCallBack(Uint32 Codepoint)
+ * \brief Called on keyboard interrupt
+ */
+void VT_KBCallBack(Uint32 Codepoint)
+{
+       tVTerm  *term = &gVT_Terminals[giVT_CurrentTerminal];
+       
+       term->InputBuffer[ term->InputWrite ] = Codepoint;
+       term->InputWrite ++;
+       term->InputWrite %= MAX_INPUT_CHARS;
+       if(term->InputRead == term->InputWrite) {
+               term->InputRead ++;
+               term->InputRead %= MAX_INPUT_CHARS;
+       }
+}
+
 /**
  * \fn void VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count)
  * \brief Print a string to the Virtual Terminal
@@ -280,6 +341,15 @@ void VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count)
                        VT_int_PutChar(Term, val);
                }
        }
+       
+       // Update cursor
+       if(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);
+       }
 }
 
 /**
@@ -461,11 +531,12 @@ void VT_int_UpdateScreen( tVTerm *Term, int UpdateAll )
                        &Term->Text[Term->ViewPos]
                        );
        } else {
+                int    pos = Term->WritePos - Term->WritePos % Term->Width;
                VFS_WriteAt(
                        giVT_OutputDevHandle,
-                       Term->ViewPos*sizeof(tVT_Char),
+                       (pos - Term->ViewPos)*sizeof(tVT_Char),
                        Term->Width*sizeof(tVT_Char),
-                       &Term->Text[Term->ViewPos]
+                       &Term->Text[pos]
                        );
        }
 }

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