Fixing select() implementation (and usage)
[tpg/acess2.git] / Kernel / drv / vterm.c
index 3e47f93..fc89b3a 100644 (file)
@@ -9,6 +9,7 @@
 #include <tpl_drv_keyboard.h>
 #include <tpl_drv_terminal.h>
 #include <errno.h>
+#include <semaphore.h>
 
 #define        USE_CTRL_ALT    0
 
@@ -56,6 +57,7 @@ typedef struct {
         int    InputRead;      //!< Input buffer read position
         int    InputWrite;     //!< Input buffer write position
        char    InputBuffer[MAX_INPUT_CHARS8];
+       tSemaphore      InputSemaphore;
        
        tVT_Char        *Text;
        Uint32          *Buffer;
@@ -221,6 +223,7 @@ int VT_Install(char **Arguments)
                gVT_Terminals[i].Node.Read = VT_Read;
                gVT_Terminals[i].Node.Write = VT_Write;
                gVT_Terminals[i].Node.IOCtl = VT_Terminal_IOCtl;
+               Semaphore_Init(&gVT_Terminals[i].InputSemaphore, 0, MAX_INPUT_CHARS8, "VTerm", gVT_Terminals[i].Name);
        }
        
        // Add to DevFS
@@ -416,21 +419,26 @@ int VT_Root_IOCtl(tVFS_Node *Node, int Id, void *Data)
 Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
 {
         int    pos = 0;
+        int    avail;
        tVTerm  *term = &gVT_Terminals[ Node->Inode ];
        
        Mutex_Acquire( &term->ReadingLock );
-       term->ReadingThread = Threads_GetTID();
        
        // Check current mode
        switch(term->Mode)
        {
        // Text Mode (UTF-8)
        case TERM_MODE_TEXT:
-               while(pos < Length)
+               VFS_SelectNode(Node, VFS_SELECT_READ, NULL);
+               
+               avail = term->InputWrite - term->InputRead;
+               if(avail < 0)
+                       avail += MAX_INPUT_CHARS8;
+               if(avail > Length - pos)
+                       avail = Length - pos;
+               
+               while( avail -- )
                {
-                       //TODO: Sleep instead
-                       while(term->InputRead == term->InputWrite)      Threads_Sleep();
-                       
                        ((char*)Buffer)[pos] = term->InputBuffer[term->InputRead];
                        pos ++;
                        term->InputRead ++;
@@ -441,21 +449,35 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        //case TERM_MODE_FB:
        // Other - UCS-4
        default:
-               while(pos < Length)
+               VFS_SelectNode(Node, VFS_SELECT_READ, NULL);
+                       
+               avail = term->InputWrite - term->InputRead;
+               if(avail < 0)
+                       avail += MAX_INPUT_CHARS32;
+               if(avail > Length - pos)
+                       avail = Length/4 - pos;
+               
+               
+               while( avail -- )
                {
-                       while(term->InputRead == term->InputWrite)      Threads_Sleep();
                        ((Uint32*)Buffer)[pos] = ((Uint32*)term->InputBuffer)[term->InputRead];
                        pos ++;
                        term->InputRead ++;
                        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;
+       
        Mutex_Release( &term->ReadingLock );
        
-       return 0;
+       return pos;
 }
 
 /**
@@ -830,7 +852,6 @@ void VT_KBCallBack(Uint32 Codepoint)
                        term->InputRead = term->InputWrite + 1;
                        term->InputRead %= MAX_INPUT_CHARS8;
                }
-               
        }
        else
        {
@@ -844,10 +865,12 @@ void VT_KBCallBack(Uint32 Codepoint)
                }
        }
        
+       VFS_MarkAvaliable(&term->Node, 1);
+       
        // Wake up the thread waiting on us
-       if( term->ReadingThread >= 0 ) {
-               Threads_WakeTID(term->ReadingThread);
-       }
+       //if( term->ReadingThread >= 0 ) {
+       //      Threads_WakeTID(term->ReadingThread);
+       //}
 }
 
 /**
@@ -1479,6 +1502,8 @@ Uint32 VT_Colour12toN(Uint16 Col12, int Depth)
        // Fast returns
        if( Depth == 24 )       return VT_Colour12to24(Col12);
        if( Depth == 15 )       return VT_Colour12to15(Col12);
+       // - 32 is a special case, it's usually 24-bit colour with an unused byte
+       if( Depth == 32 )       return VT_Colour12to24(Col12);
        
        // Bounds checks
        if( Depth < 8 ) return 0;

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