From 1dc089a0b5b31e8e75e85128a03b7be20d4995f5 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 18 May 2013 21:47:34 +0800 Subject: [PATCH] Kernel - Integrated PTY with VTerm, userland currently broken --- KernelLand/Kernel/Makefile | 1 + KernelLand/Kernel/drv/pty.c | 37 +- KernelLand/Kernel/drv/vterm.c | 329 +++++------------- KernelLand/Kernel/drv/vterm.h | 18 +- KernelLand/Kernel/drv/vterm_input.c | 65 +--- KernelLand/Kernel/drv/vterm_termbuf.c | 6 +- KernelLand/Kernel/include/api_drv_common.h | 66 +--- KernelLand/Kernel/include/drv_pty.h | 8 +- KernelLand/Kernel/system.c | 6 +- KernelLand/Modules/Makefile.tpl | 1 + .../include_exp/acess/devices.h | 88 +++-- 11 files changed, 193 insertions(+), 432 deletions(-) diff --git a/KernelLand/Kernel/Makefile b/KernelLand/Kernel/Makefile index 136706e8..1628f9b9 100644 --- a/KernelLand/Kernel/Makefile +++ b/KernelLand/Kernel/Makefile @@ -23,6 +23,7 @@ endif ASFLAGS += -D ARCHDIR_IS_$(ARCHDIR)=1 -D PLATFORM_is_$(PLATFORM)=1 CPPFLAGS += -I./include -I./arch/$(ARCHDIR)/include -D_MODULE_NAME_=\"Kernel\" +CPPFLAGS += -I../../Usermode/Libraries/ld-acess.so_src/include_exp/ # Syscalls CPPFLAGS += -D ARCH=$(ARCH) -D ARCHDIR=$(ARCHDIR) -D PLATFORM=\"$(PLATFORM)\" -D ARCHDIR_IS_$(ARCHDIR)=1 -D PLATFORM_is_$(PLATFORM)=1 CPPFLAGS += -D KERNEL_VERSION=$(KERNEL_VERSION) -ffreestanding CFLAGS += -Wall -fno-stack-protector -Wstrict-prototypes -std=gnu99 -g -fno-omit-frame-pointer diff --git a/KernelLand/Kernel/drv/pty.c b/KernelLand/Kernel/drv/pty.c index 3ffe82b2..ace6c53b 100644 --- a/KernelLand/Kernel/drv/pty.c +++ b/KernelLand/Kernel/drv/pty.c @@ -5,7 +5,7 @@ * drv/pty.c * - Pseudo Terminals */ -#define DEBUG 1 +#define DEBUG 0 #include #include #include @@ -30,6 +30,7 @@ struct sPTY void *OutputHandle; tPTY_OutputFcn OutputFcn; tPTY_ReqResize ReqResize; + tPTY_ModeSet ModeSet; struct ptymode Mode; struct ptydims Dims; @@ -121,7 +122,7 @@ int PTY_Install(char **Arguments) } // --- Management --- -tPTY *PTY_Create(const char *Name, void *Handle, tPTY_OutputFcn Output, tPTY_ReqResize ReqResize) +tPTY *PTY_Create(const char *Name, void *Handle, tPTY_OutputFcn Output, tPTY_ReqResize ReqResize, tPTY_ModeSet ModeSet) { tPTY **prev_np = NULL; size_t namelen; @@ -188,6 +189,7 @@ tPTY *PTY_Create(const char *Name, void *Handle, tPTY_OutputFcn Output, tPTY_Req ret->OutputHandle = Handle; ret->OutputFcn = Output; ret->ReqResize = ReqResize; + ret->ModeSet = ModeSet; // - Server node ret->ServerNode.ImplPtr = ret; ret->ServerNode.Type = &gPTY_NodeType_Server; @@ -229,11 +231,19 @@ int PTY_SetAttrib(tPTY *PTY, const struct ptydims *Dims, const struct ptymode *M return -1; } PTY->Mode = *Mode; - if( !WasClient && !PTY->OutputFcn ) + if( !WasClient ) { - Log_Warning("PTY", "TODO: Need to stop client output until modeset has been ACKed"); - // Block write until acked - // ACK by server doing GETMODE + if( PTY->ModeSet && PTY->ModeSet(PTY->OutputHandle, Mode) ) + { + errno = EINVAL; + return -1; + } + else if( !PTY->OutputFcn ) + { + Log_Warning("PTY", "TODO: Need to stop client output until modeset has been ACKed"); + // Block write until acked + // ACK by server doing GETMODE + } } } if( Dims ) @@ -504,9 +514,9 @@ tVFS_Node *PTY_FindDir(tVFS_Node *Node, const char *Name, Uint Flags) tVFS_Node *PTY_MkNod(tVFS_Node *Node, const char *Name, Uint Mode) { // zero-length name means a numbered pty has been requested - if( Name[0] == '\0' ) + if( Name[0] == '\0' || (Name[0] == '#' && Name[1] == '\0') ) { - tPTY *ret = PTY_Create(NULL, NULL, NULL, NULL); + tPTY *ret = PTY_Create(NULL, NULL, NULL, NULL, NULL); if( !ret ) return NULL; return &ret->ServerNode; @@ -515,7 +525,7 @@ tVFS_Node *PTY_MkNod(tVFS_Node *Node, const char *Name, Uint Mode) // Otherwise return a named PTY // TODO: Should the request be for 's' or just '' - tPTY *ret = PTY_Create(Name, NULL, NULL, NULL); + tPTY *ret = PTY_Create(Name, NULL, NULL, NULL, NULL); if(!ret) return NULL; return &ret->ServerNode; @@ -575,7 +585,7 @@ size_t PTY_WriteClient(tVFS_Node *Node, off_t Offset, size_t Length, const void // Write to either FIFO or directly to output function if( pty->OutputFcn ) { - pty->OutputFcn(pty->OutputHandle, Buffer, Length, pty->Mode.OutputMode); + pty->OutputFcn(pty->OutputHandle, Length, Buffer); } else { @@ -598,7 +608,7 @@ int PTY_IOCtlClient(tVFS_Node *Node, int ID, void *Data) { case DRV_IOCTL_TYPE: return DRV_TYPE_TERMINAL; case DRV_IOCTL_IDENT: memcpy(Data, "PTY\0", 4); return 0; - case DRV_IOCTL_VER: return 0x100; + case DRV_IOCTL_VERSION: return 0x100; case DRV_IOCTL_LOOKUP: return 0; case PTY_IOCTL_GETMODE: @@ -624,7 +634,7 @@ void PTY_ReferenceClient(tVFS_Node *Node) { Node->ReferenceCount ++; // TODO: Add PID to list of client PIDs - Log_Notice("PTY", "TODO: List of client PIDs"); +// Log_Notice("PTY", "ReferenceClient: TODO - List of client PIDs"); } void PTY_CloseClient(tVFS_Node *Node) @@ -633,6 +643,7 @@ void PTY_CloseClient(tVFS_Node *Node) Node->ReferenceCount --; // Remove PID from list + // TODO: Maintain list of client processes // Free structure if this was the last open handle if( Node->ReferenceCount == 0 && pty->ServerNode.ReferenceCount == 0 ) @@ -687,7 +698,7 @@ int PTY_IOCtlServer(tVFS_Node *Node, int ID, void *Data) { case DRV_IOCTL_TYPE: return DRV_TYPE_TERMINAL; case DRV_IOCTL_IDENT: memcpy(Data, "PTY\0", 4); return 0; - case DRV_IOCTL_VER: return 0x100; + case DRV_IOCTL_VERSION: return 0x100; case DRV_IOCTL_LOOKUP: return 0; case PTY_IOCTL_GETMODE: diff --git a/KernelLand/Kernel/drv/vterm.c b/KernelLand/Kernel/drv/vterm.c index 01612dc7..a6cf771f 100644 --- a/KernelLand/Kernel/drv/vterm.c +++ b/KernelLand/Kernel/drv/vterm.c @@ -34,36 +34,24 @@ extern void Debug_SetKTerminal(const char *File); // === PROTOTYPES === int VT_Install(char **Arguments); - 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, 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); +void VT_int_PutFBData(tVTerm *Term, size_t Offset, size_t Length, const void *Data); +void VT_PTYOutput(void *Handle, size_t Length, const void *Data); + int VT_PTYResize(void *Handle, const struct ptydims *Dims); + int VT_PTYModeset(void *Handle, const struct ptymode *Mode); // === CONSTANTS === // === GLOBALS === -MODULE_DEFINE(0, VERSION, VTerm, VT_Install, NULL, NULL); +MODULE_DEFINE(0, VERSION, VTerm, VT_Install, NULL, "PTY", 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, + .Flags = 0, .Size = NUM_VTS, .Inode = -1, .NumACLs = 0, @@ -182,21 +170,19 @@ int VT_Install(char **Arguments) 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); + VT_int_Resize( &gVT_Terminals[i], giVT_RealWidth, giVT_RealHeight ); + gVT_Terminals[i].Mode = PTYBUFFMT_TEXT; + char name[] = {'v','t','0'+i,'\0'}; + gVT_Terminals[i].PTY = PTY_Create(name, &gVT_Terminals[i], + VT_PTYOutput, VT_PTYResize, VT_PTYModeset); + struct ptymode mode = { + .OutputMode = PTYBUFFMT_TEXT, + .InputMode = PTYIMODE_CANON|PTYIMODE_ECHO + }; + PTY_SetAttrib(gVT_Terminals[i].PTY, NULL, &mode, 0); } // Add to DevFS @@ -204,7 +190,7 @@ int VT_Install(char **Arguments) // Set kernel output to VT0 Log_Debug("VTerm", "Setting kernel output to VT#0"); - Debug_SetKTerminal("/Devices/VTerm/0"); + Debug_SetKTerminal("/Devices/pts/vt0c"); return MODULE_ERR_OK; } @@ -242,6 +228,7 @@ void VT_SetResolution(int Width, int Height) VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_GETSETMODE, &tmp ); // Resize text terminals if needed + // - VT0 check is for the first resolution set if( gVT_Terminals[0].Text && (giVT_RealWidth != mode.width || giVT_RealHeight != mode.height) ) { int newBufSize = (giVT_RealWidth/giVT_CharWidth) @@ -267,50 +254,6 @@ void VT_SetResolution(int Width, int Height) } } -/** - * \fn char *VT_ReadDir(tVFS_Node *Node, int Pos) - * \brief Read from the VTerm Directory - */ -int VT_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]) -{ - if(Pos < 0) return -EINVAL; - if(Pos >= NUM_VTS) return -EINVAL; - strncpy(Dest, gVT_Terminals[Pos].Name, FILENAME_MAX); - return 0; -} - -/** - * \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, Uint Flags) -{ - 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 @@ -351,185 +294,102 @@ int VT_Root_IOCtl(tVFS_Node *Node, int Id, void *Data) return 0; } -/** - * \brief Read from a virtual terminal - */ -size_t VT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags) +void VT_int_PutFBData(tVTerm *Term, size_t Offset, size_t Length, const void *Buffer) { - 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 ); + size_t maxlen = Term->Width * Term->Height * 4; + + if( Offset >= maxlen ) + return ; + + Length = MIN(Length, maxlen - Offset); - // Check current mode - switch(term->Mode) + // If the terminal is currently shown, write directly to the screen + if( Term == gpVT_CurTerm ) { - // Text Mode (UTF-8) - case TERM_MODE_TEXT: - VT_int_UpdateCursor(term, 1); - - 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) - avail = Length; + // Center the terminal vertically + if( giVT_RealHeight > Term->Height ) + Offset += (giVT_RealHeight - Term->Height) / 2 * Term->Width * 4; - pos = 0; - while( avail -- ) + // If the terminal is not native width, center it horizontally + if( giVT_RealWidth > Term->Width ) { - ((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: - 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; + // 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 = (const Uint32*)Buffer + Term->Width; + dst_ofs += giVT_RealWidth * 4; + } } - - avail = term->InputWrite - term->InputRead; - if(avail < 0) - avail += MAX_INPUT_CHARS32; - Length /= 4; - if(avail > Length) - avail = Length; - - codepoint_in = (void*)term->InputBuffer; - codepoint_buf = Buffer; - - pos = 0; - while( avail -- ) + // otherwise, just go directly to the screen + else { - codepoint_buf[pos] = codepoint_in[term->InputRead]; - pos ++; - term->InputRead ++; - while(term->InputRead >= MAX_INPUT_CHARS32) - term->InputRead -= MAX_INPUT_CHARS32; + VFS_WriteAt( giVT_OutputDevHandle, Offset, Length, Buffer ); } - 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; + // If not active, write to the backbuffer (allocating if needed) + else + { + if( !Term->Buffer ) + Term->Buffer = malloc( Term->Width * Term->Height * 4 ); + // Copy to the local cache + memcpy( (char*)Term->Buffer + Offset, Buffer, Length ); + } } -/** - * \brief Write to a virtual terminal - */ -size_t VT_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags) +void VT_PTYOutput(void *Handle, size_t Length, const void *Data) { - tVTerm *term = &gVT_Terminals[ Node->Inode ]; - int size; - - // Write + tVTerm *term = Handle; switch( term->Mode ) { - // Print Text - case TERM_MODE_TEXT: - VT_int_PutString(term, Buffer, Length); + case PTYBUFFMT_TEXT: + VT_int_PutString(term, Data, Length); break; - - // Framebuffer :) - case TERM_MODE_FB: - // - Sanity Checking - size = term->Width*term->Height*4; - if( 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 ) { - 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 ); - } + case PTYBUFFMT_FB: + // TODO: How do offset? + VT_int_PutFBData(term, 0, Length, Data); 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 ); - } + case PTYBUFFMT_2DCMD: + // TODO: Impliment 2D commands + break; + case PTYBUFFMT_3DCMD: + // TODO: Impliment 3D commands break; } - - return Length; } +int VT_PTYResize(void *Handle, const struct ptydims *Dims) +{ + tVTerm *term = Handle; + int newW = Dims->W * (term->Mode == PTYBUFFMT_TEXT ? giVT_CharWidth : 1); + int newH = Dims->H * (term->Mode == PTYBUFFMT_TEXT ? giVT_CharHeight : 1); + if( newW > giVT_RealWidth || newH > giVT_RealHeight ) + return 1; + VT_int_Resize(term, newW, newH); + return 0; +} + +int VT_PTYModeset(void *Handle, const struct ptymode *Mode) +{ + tVTerm *term = Handle; + term->Mode = (Mode->OutputMode & PTYOMODE_BUFFMT); + return 0; +} + +#if 0 /** * \fn int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data) * \brief Call an IO Control on a virtual terminal @@ -734,6 +594,7 @@ void VT_Terminal_Close(tVFS_Node *Node) { // Remove PID from list } +#endif /** * \fn void VT_SetTerminal(int ID) diff --git a/KernelLand/Kernel/drv/vterm.h b/KernelLand/Kernel/drv/vterm.h index 9cfb2b9b..7b01366f 100644 --- a/KernelLand/Kernel/drv/vterm.h +++ b/KernelLand/Kernel/drv/vterm.h @@ -12,6 +12,7 @@ #include // tVT_Char #include #include +#include // === CONSTANTS === #define MAX_INPUT_CHARS32 64 @@ -46,8 +47,6 @@ struct sVTerm 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) short Width; //!< Virtual Width short Height; //!< Virtual Height short TextWidth; //!< Text Virtual Width @@ -70,25 +69,16 @@ struct sVTerm int VideoCursorX; int VideoCursorY; - 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]; Uint32 RawScancode; //!< last raw scancode recieved -// tSemaphore InputSemaphore; - tPGID OwningProcessGroup; //!< The process group that owns the terminal - Uint32 *Buffer; // TODO: Do I need to keep this about? // When should it be deallocated? on move to text mode, or some other time // Call set again, it's freed, and if NULL it doesn't get reallocated. tVideo_IOCtl_Bitmap *VideoCursor; - - char Name[2]; //!< Name of the terminal - tVFS_Node Node; + + tPTY *PTY; }; // === GOBALS === @@ -121,7 +111,7 @@ extern void VT_int_PutString(tVTerm *Term, const Uint8 *Buffer, Uint Count); extern void VT_int_PutChar(tVTerm *Term, Uint32 Ch); extern void VT_int_ScrollText(tVTerm *Term, int Count); extern void VT_int_ClearLine(tVTerm *Term, int Num); -extern void VT_int_ChangeMode(tVTerm *Term, int NewMode, int NewWidth, int NewHeight); +extern void VT_int_Resize(tVTerm *Term, int NewWidth, int NewHeight); extern void VT_int_ToggleAltBuffer(tVTerm *Term, int Enabled); #endif diff --git a/KernelLand/Kernel/drv/vterm_input.c b/KernelLand/Kernel/drv/vterm_input.c index b44564ec..3e86087b 100644 --- a/KernelLand/Kernel/drv/vterm_input.c +++ b/KernelLand/Kernel/drv/vterm_input.c @@ -118,7 +118,7 @@ void VT_KBCallBack(Uint32 Codepoint) } // Encode key - if(term->Mode == TERM_MODE_TEXT) + if(term->Mode == PTYBUFFMT_TEXT) { Uint8 buf[6] = {0}; int len = 0; @@ -231,70 +231,11 @@ void VT_KBCallBack(Uint32 Codepoint) return; } - // TODO: Implement Ctrl-C etc -#if 0 - // Handle meta characters - if( !(term->Flags & VT_FLAG_RAWIN) ) - { - // Implementation options for Ctrl-C -> SIGINT - // - Kernel-land: here in the VT - // > Pros: No userland change needed - // > Cons: Requires process groups - // - User-land, in the shell - // > Pros: Less threading changes - // > Cons: Needs the shell to get all user input before the app, worse latency - // > Won't work with bash etc - switch(buf[0]) - { - case '\3': // ^C - - break; - } - } -#endif - - // Write - if( MAX_INPUT_CHARS8 - term->InputWrite >= len ) { - memcpy( &term->InputBuffer[term->InputWrite], buf, len ); - } - else { - memcpy( &term->InputBuffer[term->InputWrite], buf, MAX_INPUT_CHARS8 - term->InputWrite ); - memcpy( &term->InputBuffer[0], buf, len - (MAX_INPUT_CHARS8 - term->InputWrite) ); - } - // Roll the buffer over - term->InputWrite += len; - term->InputWrite %= MAX_INPUT_CHARS8; - if( (term->InputWrite - term->InputRead + MAX_INPUT_CHARS8)%MAX_INPUT_CHARS8 < len ) { - term->InputRead = term->InputWrite + 1; - term->InputRead %= MAX_INPUT_CHARS8; - } + PTY_SendInput(term->PTY, (void*)buf, len); } else { - // Encode the raw key event - Uint32 *raw_in = (void*)term->InputBuffer; - - #if 0 - // Drop new keys - if( term->InputWrite == term->InputRead ) - return ; - #endif - - raw_in[ term->InputWrite ] = Codepoint; - term->InputWrite ++; - if(term->InputWrite >= MAX_INPUT_CHARS32) - term->InputWrite -= MAX_INPUT_CHARS32; - - #if 1 - // TODO: Should old or new be dropped? - if(term->InputRead == term->InputWrite) { - term->InputRead ++; - if( term->InputRead >= MAX_INPUT_CHARS32 ) - term->InputRead -= MAX_INPUT_CHARS32; - } - #endif + PTY_SendInput(term->PTY, (void*)&Codepoint, sizeof(Codepoint)); } - - VFS_MarkAvaliable(&term->Node, 1); } diff --git a/KernelLand/Kernel/drv/vterm_termbuf.c b/KernelLand/Kernel/drv/vterm_termbuf.c index e03302a1..ee543858 100644 --- a/KernelLand/Kernel/drv/vterm_termbuf.c +++ b/KernelLand/Kernel/drv/vterm_termbuf.c @@ -288,7 +288,7 @@ void VT_int_ClearLine(tVTerm *Term, int Num) * \param NewWidth New framebuffer width * \param NewHeight New framebuffer height */ -void VT_int_ChangeMode(tVTerm *Term, int NewMode, int NewWidth, int NewHeight) +void VT_int_Resize(tVTerm *Term, int NewWidth, int NewHeight) { int oldW = Term->Width; int oldTW = Term->TextWidth; @@ -302,8 +302,6 @@ void VT_int_ChangeMode(tVTerm *Term, int NewMode, int NewWidth, int NewHeight) if(NewWidth > giVT_RealWidth) NewWidth = giVT_RealWidth; if(NewHeight > giVT_RealHeight) NewHeight = giVT_RealHeight; - Term->Mode = NewMode; - // Fast exit if no resolution change if(NewWidth == Term->Width && NewHeight == Term->Height) return ; @@ -362,7 +360,7 @@ void VT_int_ChangeMode(tVTerm *Term, int NewMode, int NewWidth, int NewHeight) // Debug #if 0 - switch(NewMode) + switch(Term->Mode) { case TERM_MODE_TEXT: Log_Log("VTerm", "Set VT %p to text mode (%ix%i)", diff --git a/KernelLand/Kernel/include/api_drv_common.h b/KernelLand/Kernel/include/api_drv_common.h index 59bef5fe..e1bb3f37 100644 --- a/KernelLand/Kernel/include/api_drv_common.h +++ b/KernelLand/Kernel/include/api_drv_common.h @@ -34,54 +34,7 @@ #ifndef _API_DRV_COMMON_H #define _API_DRV_COMMON_H -/** - * \enum eTplDrv_IOCtl - * \brief Common IOCtl Calls - */ -enum eTplDrv_IOCtl { - /** - * ioctl(...) - * \brief Get driver type - * \return The relevant entry from ::eTplDrv_Type - */ - DRV_IOCTL_TYPE, - - /** - * ioctl(..., char *dest[32]) - * \brief Get driver identifier string - * \return 0 on no error - * - * This call sets the 32-byte array \a dest to the drivers 31 charater - * identifier. This identifier must be unique to the driver series. - */ - DRV_IOCTL_IDENT, - - /** - * ioctl(...) - * \brief Get driver version number - * \return 24-bit BCD version number (2.2.2) - * - * This call returns the 6-digit (2 major, 2 minor, 2 patch) version - * number of the driver. - */ - DRV_IOCTL_VERSION, - - /** - * ioctl(..., char *name) - * \brief Get a IOCtl call ID from a symbolic name - * \return ID number of the call, or 0 if not found - * - * This call allows user applications to not need to know the ID numbers - * of this driver's IOCtl calls by taking a string and returning the - * IOCtl call number associated with that method name. - */ - DRV_IOCTL_LOOKUP, - - /** - * \brief First non-reserved IOCtl number for driver extension - */ - DRV_IOCTL_USERMIN = 0x1000, -}; +#include /** * \brief eTplDrv_IOCtl.DRV_IOCTL_LOOKUP names for the core IOCtls @@ -121,21 +74,4 @@ enum eTplDrv_IOCtl { return tmp;\ } -/** - * \enum eTplDrv_Type - * \brief Driver Types returned by DRV_IOCTL_TYPE - */ -enum eTplDrv_Type { - DRV_TYPE_NULL, //!< NULL Type - Custom Interface - DRV_TYPE_MISC, //!< Miscelanious Compilant - Supports the core calls - DRV_TYPE_TERMINAL, //!< Terminal - see api_drv_terminal.h - DRV_TYPE_VIDEO, //!< Video - see api_drv_video.h - DRV_TYPE_SOUND, //!< Audio - DRV_TYPE_DISK, //!< Disk - see api_drv_disk.h - DRV_TYPE_KEYBOARD, //!< Keyboard - see api_drv_keyboard.h - DRV_TYPE_MOUSE, //!< Mouse - DRV_TYPE_JOYSTICK, //!< Joystick / Gamepad - DRV_TYPE_NETWORK //!< Network Device - see api_drv_network.h -}; - #endif diff --git a/KernelLand/Kernel/include/drv_pty.h b/KernelLand/Kernel/include/drv_pty.h index a86ca8be..bb316296 100644 --- a/KernelLand/Kernel/include/drv_pty.h +++ b/KernelLand/Kernel/include/drv_pty.h @@ -8,13 +8,15 @@ #ifndef _KERNEL_DRV_PTY_H_ #define _KERNEL_DRV_PTY_H_ -#include "../../../Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices/pty.h" +// Userland +#include typedef struct sPTY tPTY; -typedef void (*tPTY_OutputFcn)(void *Handle, const void *Data, size_t Length, unsigned int OutMode); +typedef void (*tPTY_OutputFcn)(void *Handle, size_t Length, const void *Data); typedef int (*tPTY_ReqResize)(void *Handle, const struct ptydims *Dims); +typedef int (*tPTY_ModeSet)(void *Handle, const struct ptymode *Mode); -extern tPTY *PTY_Create(const char *Name, void *Handle, tPTY_OutputFcn OutputFcn, tPTY_ReqResize ReqResize); +extern tPTY *PTY_Create(const char *Name, void *Handle, tPTY_OutputFcn OutputFcn, tPTY_ReqResize ReqResize, tPTY_ModeSet ModeSet); extern int PTY_SetAttrib(tPTY *PTY, const struct ptydims *Dims, const struct ptymode *Mode, int WasClient); extern void PTY_Close(tPTY *PTY); extern size_t PTY_SendInput(tPTY *PTY, const char *InputString, size_t InputLength); diff --git a/KernelLand/Kernel/system.c b/KernelLand/Kernel/system.c index 7938723a..0506f3ac 100644 --- a/KernelLand/Kernel/system.c +++ b/KernelLand/Kernel/system.c @@ -48,15 +48,15 @@ void System_Init(char *CommandLine) if(Proc_Clone(CLONE_VM|CLONE_NOUSER) == 0) { const char *args[] = {gsInitBinary, 0}; - VFS_Open("/Devices/VTerm/0", VFS_OPENFLAG_READ|VFS_OPENFLAG_USER); // 0: stdin - VFS_Open("/Devices/VTerm/0", VFS_OPENFLAG_WRITE|VFS_OPENFLAG_USER); // 1: stdout + VFS_Open("/Devices/pts/vt0c", VFS_OPENFLAG_READ|VFS_OPENFLAG_USER); // 0: stdin + VFS_Open("/Devices/pts/vt0c", VFS_OPENFLAG_WRITE|VFS_OPENFLAG_USER); // 1: stdout Proc_Execve(gsInitBinary, args, &args[1], 0); Log_KernelPanic("System", "Unable to spawn init '%s'", gsInitBinary); } // Set the debug to be echoed to the terminal Log_Log("Config", "Kernel now echoes to VT7 (Ctrl-Alt-F8)"); - Debug_SetKTerminal("/Devices/VTerm/7"); + Debug_SetKTerminal("/Devices/pts/vt7c"); } /** diff --git a/KernelLand/Modules/Makefile.tpl b/KernelLand/Modules/Makefile.tpl index 19fd77ea..b0189bb7 100644 --- a/KernelLand/Modules/Makefile.tpl +++ b/KernelLand/Modules/Makefile.tpl @@ -11,6 +11,7 @@ LIBINCLUDES := $(addsuffix /include,$(LIBINCLUDES)) CPPFLAGS := -I$(ACESSDIR)/KernelLand/Kernel/include -I$(ACESSDIR)/KernelLand/Kernel/arch/$(ARCHDIR)/include CPPFLAGS += -I$(ACESSDIR)/KernelLand/Modules +CPPFLAGS += -I$(ACESSDIR)/Usermode/Libraries/ld-acess.so_src/include_exp/ CPPFLAGS += -DARCH=$(ARCH) -DARCH_is_$(ARCH) -DARCHDIR_is_$(ARCHDIR) CPPFLAGS += $(_CPPFLAGS) CPPFLAGS += $(LIBINCLUDES) -ffreestanding diff --git a/Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices.h b/Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices.h index 8c0955aa..9ee77b0d 100644 --- a/Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices.h +++ b/Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices.h @@ -1,50 +1,70 @@ /** - * \file drivers.h + * Acess2 User Core + * - By John Hodge (thePowersGang) + * + * acess/devices.h + * - Core device IOCtls */ -#ifndef _SYS_DRIVERS_H -#define _SYS_DRIVERS_H +#ifndef _ACESS_DRIVERS_H +#define _ACESS_DRIVERS_H // === COMMON === enum eDrv_Common { + /** + * ioctl(...) + * \brief Get driver type + * \return The relevant entry from ::eTplDrv_Type + */ DRV_IOCTL_TYPE, + + /** + * ioctl(..., char *dest[32]) + * \brief Get driver identifier string + * \return 0 on no error + * + * This call sets the 32-byte array \a dest to the drivers 31 character + * identifier. This identifier must be unique to the driver series. + */ DRV_IOCTL_IDENT, - DRV_IOCTL_VER, + + /** + * ioctl(...) + * \brief Get driver version number + * \return 24-bit BCD version number (2.2.2) + * + * This call returns the 6-digit (2 major, 2 minor, 2 patch) version + * number of the driver. + */ + DRV_IOCTL_VERSION, + + /** + * ioctl(..., char *name) + * \brief Get a IOCtl call ID from a symbolic name + * \return ID number of the call, or 0 if not found + * + * This call allows user applications to not need to know the ID numbers + * of this driver's IOCtl calls by taking a string and returning the + * IOCtl call number associated with that method name. + */ DRV_IOCTL_LOOKUP, + + /** + * \brief First non-reserved IOCtl number for driver extension + */ + DRV_IOCTL_USERMIN = 0x1000, }; enum eDrv_Types { - DRV_TYPE_NULL, //!< NULL Type - Custom Interface - DRV_TYPE_TERMINAL, //!< Terminal - DRV_TYPE_VIDEO, //!< Video - LFB + DRV_TYPE_NULL, //!< NULL Type - Custom Interface (must support core calls) + DRV_TYPE_MISC, //!< Miscelanious Compilant - Supports the core calls + DRV_TYPE_TERMINAL, //!< Terminal - see api_drv_terminal.h + DRV_TYPE_VIDEO, //!< Video - see api_drv_video.h DRV_TYPE_SOUND, //!< Audio + DRV_TYPE_DISK, //!< Disk - see api_drv_disk.h + DRV_TYPE_KEYBOARD, //!< Keyboard - see api_drv_keyboard.h DRV_TYPE_MOUSE, //!< Mouse - DRV_TYPE_JOYSTICK //!< Joystick / Gamepad -}; - -// === VIDEO === -enum eDrv_Video { - VID_IOCTL_SETMODE = 4, - VID_IOCTL_GETMODE, - VID_IOCTL_FINDMODE, - VID_IOCTL_MODEINFO, - VID_IOCTL_REQLFB // Request LFB -}; -struct sVideo_IOCtl_Mode { - short id; - unsigned short width; - unsigned short height; - unsigned short bpp; + DRV_TYPE_JOYSTICK, //!< Joystick / Gamepad + DRV_TYPE_NETWORK //!< Network Device - see api_drv_network.h }; -typedef struct sVideo_IOCtl_Mode tVideo_IOCtl_Mode; //!< Mode Type - -// === MOUSE === -enum eDrv_Mouse { - MSE_IOCTL_SENS = 4, - MSE_IOCTL_MAX_X, - MSE_IOCTL_MAX_Y -}; - -// === Terminal === -#include "devices/terminal.h" #endif -- 2.20.1