X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fdrv%2Fvterm.c;h=c2f068546b6cb32381017845412dc9db4d805c34;hb=17c447e4977d83c1b6aadcb80f4542b4802e9b21;hp=b940afa8b2fed10e949d4beb33650f42366f1fa9;hpb=a928d1d2a70761eece125cdbe9950ec0b1112ce3;p=tpg%2Facess2.git diff --git a/Kernel/drv/vterm.c b/Kernel/drv/vterm.c index b940afa8..c2f06854 100644 --- a/Kernel/drv/vterm.c +++ b/Kernel/drv/vterm.c @@ -39,7 +39,6 @@ enum eVT_InModes { typedef struct { int Mode; //!< Current Mode (see ::eTplTerminal_Modes) int Flags; //!< Flags (see VT_FLAG_*) - short NewWidth; //!< Un-applied dimensions (Width) short NewHeight; //!< Un-applied dimensions (Height) @@ -52,6 +51,8 @@ typedef struct { int WritePos; //!< Write Buffer Offset (Text Only) Uint32 CurColour; //!< Current Text Colour + tMutex ReadingLock; //!< Lock the VTerm when a process is reading from it + tTID ReadingThread; //!< Owner of the lock int InputRead; //!< Input buffer read position int InputWrite; //!< Input buffer write position char InputBuffer[MAX_INPUT_CHARS8]; @@ -71,7 +72,7 @@ extern void Debug_SetKTerminal(char *File); void VT_InitOutput(void); void VT_InitInput(void); char *VT_ReadDir(tVFS_Node *Node, int Pos); -tVFS_Node *VT_FindDir(tVFS_Node *Node, char *Name); +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, void *Buffer); @@ -148,12 +149,10 @@ int VT_Install(char **Arguments) val = arg + strpos(arg, '='); *val++ = '\0'; if( strcmp(opt, "Video") == 0 ) { - if(gsVT_OutputDevice) free(gsVT_OutputDevice); - gsVT_OutputDevice = strdup(val); + gsVT_OutputDevice = val; } else if( strcmp(opt, "Input") == 0 ) { - if(gsVT_InputDevice) free(gsVT_InputDevice); - gsVT_InputDevice = strdup(val); + gsVT_InputDevice = val; } else if( strcmp(opt, "Width") == 0 ) { giVT_RealWidth = atoi( val ); @@ -167,9 +166,25 @@ int VT_Install(char **Arguments) } } + if(gsVT_OutputDevice) Modules_InitialiseBuiltin( gsVT_OutputDevice ); + if(gsVT_InputDevice) Modules_InitialiseBuiltin( gsVT_InputDevice ); + // Apply Defaults - if(!gsVT_OutputDevice) gsVT_OutputDevice = "/Devices/"DEFAULT_OUTPUT; - if(!gsVT_InputDevice) gsVT_InputDevice = "/Devices/"DEFAULT_INPUT; + if(!gsVT_OutputDevice) gsVT_OutputDevice = DEFAULT_OUTPUT; + if(!gsVT_InputDevice) gsVT_InputDevice = DEFAULT_INPUT; + + // Create 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); @@ -310,12 +325,12 @@ char *VT_ReadDir(tVFS_Node *Node, int Pos) } /** - * \fn tVFS_Node *VT_FindDir(tVFS_Node *Node, char *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, char *Name) +tVFS_Node *VT_FindDir(tVFS_Node *Node, const char *Name) { int num; @@ -388,6 +403,9 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) int pos = 0; tVTerm *term = &gVT_Terminals[ Node->Inode ]; + Mutex_Acquire( &term->ReadingLock ); + term->ReadingThread = Threads_GetTID(); + // Check current mode switch(term->Mode) { @@ -395,7 +413,8 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) case TERM_MODE_TEXT: while(pos < Length) { - while(term->InputRead == term->InputWrite) Threads_Yield(); + //TODO: Sleep instead + while(term->InputRead == term->InputWrite) Threads_Sleep(); ((char*)Buffer)[pos] = term->InputBuffer[term->InputRead]; pos ++; @@ -409,7 +428,7 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) default: while(pos < Length) { - while(term->InputRead == term->InputWrite) Threads_Yield(); + while(term->InputRead == term->InputWrite) Threads_Sleep(); ((Uint32*)Buffer)[pos] = ((Uint32*)term->InputBuffer)[term->InputRead]; pos ++; term->InputRead ++; @@ -417,6 +436,10 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) } break; } + + term->ReadingThread = -1; + Mutex_Release( &term->ReadingLock ); + return 0; } @@ -804,6 +827,11 @@ void VT_KBCallBack(Uint32 Codepoint) term->InputRead %= MAX_INPUT_CHARS32; } } + + // Wake up the thread waiting on us + if( term->ReadingThread >= 0 ) { + Threads_WakeTID(term->ReadingThread); + } } /** @@ -854,17 +882,6 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer) } while(c == ';'); } - /* - // Get string (what does this do?) - if(c == '"') { - c = Buffer[j++]; - while(c != '"') - c = Buffer[j++]; - } - */ - - //Log_Debug("VTerm", "argc = %i", argc); - // Get Command if( ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) {