Usermode/GUI Terminal - Added setting of controlling PGID
[tpg/acess2.git] / Usermode / Applications / gui_shell_src / main.c
index ec88bf3..822f28b 100644 (file)
 #include "include/vt100.h"
 #include <string.h>
 #include <unicode.h>
+#include <errno.h>
+#include <acess/devices/pty.h>
 
 // === PROTOTYPES ===
  int   main(int argc, char *argv[], const char **envp);
  int   Term_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated);
  int   Term_MouseHandler(tHWND Window, int bPress, int Button, int Row, int Col);
-void   Term_HandleOutput(int Len, const char *Buf);
+void   Term_HandleOutput(tTerminal *Term, int Len, const char *Buf);
 
 // === GLOBALS ===
 tHWND  gMainWindow;
 tHWND  gMenuWindow;
- int   giChildStdin;
- int   giChildStdout;
+ int   giPTYHandle;
 
 // === CODE ===
 int main(int argc, char *argv[], const char **envp)
@@ -34,7 +35,7 @@ int main(int argc, char *argv[], const char **envp)
        AxWin3_Connect(NULL);
        
        // --- Build up window
-       gMainWindow = AxWin3_RichText_CreateWindow(NULL, 0);
+       gMainWindow = AxWin3_RichText_CreateWindow(NULL, AXWIN3_RICHTEXT_READONLY);
        AxWin3_SetWindowTitle(gMainWindow, "Terminal"); // TODO: Update title with other info
 
        gMenuWindow = AxWin3_Menu_Create(gMainWindow);
@@ -54,33 +55,38 @@ int main(int argc, char *argv[], const char **envp)
        AxWin3_RichText_SetCursorType   (gMainWindow, AXWIN3_RICHTEXT_CURSOR_INV);
        AxWin3_RichText_SetCursorBlink  (gMainWindow, 1);
 
-       // <testing>
-       AxWin3_RichText_SetLineCount(gMainWindow, 3);
-       AxWin3_RichText_SendLine(gMainWindow, 0, "First line!");
-       AxWin3_RichText_SendLine(gMainWindow, 2, "Third line! \1ff0000A red");
-       // </testing>
-
-       Display_Init(80, 25, 100);
+       tTerminal *term = Display_Init(80, 25, 100);
        AxWin3_ResizeWindow(gMainWindow, 80*8, 25*16);
        AxWin3_MoveWindow(gMainWindow, 20, 50);
        AxWin3_ShowWindow(gMainWindow, 1);
        AxWin3_FocusWindow(gMainWindow);
 
-       // Spawn shell
-       giChildStdin = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE);
-       giChildStdout = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE);
-       if( giChildStdout == -1 || giChildStdin == -1 ) {
-               perror("Oh, fsck");
-               _SysDebug("out,in = %i,%i", giChildStdout, giChildStdin);
+       // Create PTY
+       giPTYHandle = _SysOpen("/Devices/pts/ptmx", OPENFLAG_READ|OPENFLAG_WRITE);
+       if( giPTYHandle < 0 ) {
+               perror("Unable to create/open PTY");
+               _SysDebug("Unable to create/open PTY: %s", strerror(errno));
                return -1;
        }
+       // - Initialise
+       {
+               _SysIOCtl(giPTYHandle, PTY_IOCTL_SETID, "gui0");
+               struct ptymode  mode = {.InputMode = PTYIMODE_CANON|PTYIMODE_ECHO, .OutputMode=0};
+               struct ptydims  dims = {.W = 80, .H = 25};
+               _SysIOCtl(giPTYHandle, PTY_IOCTL_SETMODE, &mode);
+               _SysIOCtl(giPTYHandle, PTY_IOCTL_SETDIMS, &dims);
+       }
 
+       // Spawn shell
        {
-                int    fds[] = {giChildStdin, giChildStdout, giChildStdout};
+                int    fd = _SysOpen("/Devices/pts/gui0", OPENFLAG_READ|OPENFLAG_WRITE);
+                int    fds[] = {fd, fd, fd};
                const char      *argv[] = {"CLIShell", NULL};
                int pid = _SysSpawn("/Acess/Bin/CLIShell", argv, envp, 3, fds, NULL);
                if( pid < 0 )
-                       _SysDebug("ERROR: Shell spawn failed");
+                       _SysDebug("ERROR: Shell spawn failed: %s", strerror(errno));
+               _SysIOCtl(fd, PTY_IOCTL_SETPGRP, &pid);
+               _SysClose(fd);
        }
 
        // Main loop
@@ -89,18 +95,18 @@ int main(int argc, char *argv[], const char **envp)
                fd_set  fds;
                
                FD_ZERO(&fds);
-               FD_SET(giChildStdout, &fds);
-               AxWin3_MessageSelect(giChildStdout + 1, &fds);
+               FD_SET(giPTYHandle, &fds);
+               AxWin3_MessageSelect(giPTYHandle + 1, &fds);
                
-               if( FD_ISSET(giChildStdout, &fds) )
+               if( FD_ISSET(giPTYHandle, &fds) )
                {
                        _SysDebug("Activity on child stdout");
                        // Read and update screen
                        char    buf[128];
-                       int len = _SysRead(giChildStdout, buf, sizeof(buf));
+                       int len = _SysRead(giPTYHandle, buf, sizeof(buf));
                        if( len <= 0 )  break;
                        
-                       Term_HandleOutput(len, buf);
+                       Term_HandleOutput(term, len, buf);
                }
        }
 
@@ -144,7 +150,7 @@ int Term_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translat
                        len = WriteUTF8(buf, Translated);
                        
                        _SysDebug("Keystroke %x:%x translated to '%.*s'", KeySym, Translated, len, buf);
-                       _SysWrite(giChildStdin, buf, len);
+                       _SysWrite(giPTYHandle, buf, len);
                        
                        return 0;
                }
@@ -156,10 +162,19 @@ int Term_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translat
                case KEYSYM_LEFTARROW:
                        str = "\x1b[D";
                        break;
+               case KEYSYM_RIGHTARROW:
+                       str = "\x1b[C";
+                       break;
+               case KEYSYM_UPARROW:
+                       str = "\x1b[A";
+                       break;
+               case KEYSYM_DOWNARROW:
+                       str = "\x1b[B";
+                       break;
                }
                if( str )
                {
-                       _SysWrite(giChildStdin, str, strlen(str));
+                       _SysWrite(giPTYHandle, str, strlen(str));
                }
        }
        return 0;
@@ -170,7 +185,7 @@ int Term_MouseHandler(tHWND Window, int bPress, int Button, int Row, int Col)
        return 0;
 }
 
-void Term_HandleOutput(int Len, const char *Buf)
+void Term_HandleOutput(tTerminal *Term, int Len, const char *Buf)
 {
        // TODO: Handle graphical / accelerated modes
 
@@ -179,15 +194,15 @@ void Term_HandleOutput(int Len, const char *Buf)
 
        while( ofs < Len )
        {
-               esc_len = Term_HandleVT100(Len - ofs, Buf + ofs);
+               esc_len = Term_HandleVT100(Term, Len - ofs, Buf + ofs);
                if( esc_len < 0 ) {
-                       Display_AddText(-esc_len, Buf + ofs);
+                       Display_AddText(Term, -esc_len, Buf + ofs);
                        esc_len = -esc_len;
                }
                ofs += esc_len;
                //_SysDebug("Len = %i, ofs = %i", Len, ofs);
        }
        
-       Display_Flush();
+       Display_Flush(Term);
 }
 

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