Usermode/GUI Shell - Hacking up a GUI terminal
authorJohn Hodge (sonata) <[email protected]>
Wed, 17 Oct 2012 03:47:42 +0000 (11:47 +0800)
committerJohn Hodge (sonata) <[email protected]>
Wed, 17 Oct 2012 03:47:42 +0000 (11:47 +0800)
Usermode/Applications/gui_shell_src/Makefile [new file with mode: 0644]
Usermode/Applications/gui_shell_src/include/display.h [new file with mode: 0644]
Usermode/Applications/gui_shell_src/include/vt100.h [new file with mode: 0644]
Usermode/Applications/gui_shell_src/main.c [new file with mode: 0644]
Usermode/Applications/gui_shell_src/vt100.c [new file with mode: 0644]

diff --git a/Usermode/Applications/gui_shell_src/Makefile b/Usermode/Applications/gui_shell_src/Makefile
new file mode 100644 (file)
index 0000000..7ccfff4
--- /dev/null
@@ -0,0 +1,11 @@
+# Project: [GUI] Terminal
+
+-include ../Makefile.cfg
+
+LDFLAGS += -laxwin3
+
+OBJ = main.o
+BIN = terminal
+DIR := Apps/AxWin/3.0
+
+-include ../Makefile.tpl
diff --git a/Usermode/Applications/gui_shell_src/include/display.h b/Usermode/Applications/gui_shell_src/include/display.h
new file mode 100644 (file)
index 0000000..80bc69c
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Acess GUI Terminal
+ * - By John Hodge (thePowersGang)
+ *
+ * display.h
+ * - RichText Termianl Translation
+ */
+#ifndef _DISPLAY_H_
+#define _DISPLAY_H_
+
+extern void    Display_AddText(int Length, const char *UTF8Text);
+extern void    Display_Newline(int bCarriageReturn);
+extern void    Display_SetCursor(int Row, int Col);
+extern void    Display_MoveCursor(int RelRow, int RelCol);
+extern void    Display_ClearLine(int Dir);     // 0: All, 1: Forward, -1: Reverse
+extern void    Display_ClearLines(int Dir);    // 0: All, 1: Forward, -1: Reverse
+extern void    Display_SetForeground(uint32_t RGB);
+extern void    Display_SetBackground(uint32_t RGB);
+
+#endif
+
diff --git a/Usermode/Applications/gui_shell_src/include/vt100.h b/Usermode/Applications/gui_shell_src/include/vt100.h
new file mode 100644 (file)
index 0000000..13f830e
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Acess GUI Terminal
+ * - By John Hodge (thePowersGang)
+ *
+ * vt100.h
+ * - VT100/xterm emulation
+ */
+#ifndef _VT100_H_
+#define _VT100_H_
+
+/**
+ * Returns either a positive or negative byte count.
+ * Positive means that many bytes were used as part of the escape sequence
+ * and should not be sent to the display.
+ * Negative means that there were that many bytes before the next escape
+ * sequence (and hence those should be displayed).
+ */
+extern int     Term_HandleVT100(int Len, const char *Buf);
+
+
+#endif
+
diff --git a/Usermode/Applications/gui_shell_src/main.c b/Usermode/Applications/gui_shell_src/main.c
new file mode 100644 (file)
index 0000000..46ce398
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Acess GUI Terminal
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - Core
+ */
+#include <axwin3/axwin.h>
+#include <axwin3/menu.h>
+#include <axwin3/richtext.h>
+#include <stdio.h>
+#include "include/display.h"
+
+// === PROTOTYPES ===
+ int   main(int argc, char *argv[]);
+ int   Term_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated);
+ int   Term_MouseHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated);
+
+// === GLOBALS ===
+tHWND  gMainWindow;
+tHWND  gMenuWindow;
+ int   giChildStdin;
+ int   giChildStdout;
+
+// === CODE ===
+int main(int argc, char *argv[])
+{
+       AxWin3_Connect(NULL);
+       
+       // --- Build up window
+       gMainWindow = AxWin3_RichText_CreateWindow(NULL, 0);
+       AxWin3_SetWindowTitle(gMainWindow, "Terminal"); // TODO: Update title with other info
+
+       gMenuWindow = AxWin3_Menu_Create(gMainWindow);
+       AxWin3_Menu_AddItem(gMenuWindow, "Copy\tWin+C", NULL, NULL, NULL, 0);
+       AxWin3_Menu_AddItem(gMenuWindow, "Paste\tWin+V", NULL, NULL, NULL, 0);
+       // TODO: Populate menu  
+
+
+       // TODO: Tabs?
+       
+       AxWin3_RichText_SetKeyHandler   (gMainWindow, Term_KeyHandler);
+       AxWin3_RichText_SetMouseHandler (gMainWindow, Term_MouseHandler);
+       AxWin3_RichText_SetDefaultColour(gMainWindow, 0xFFFFFF);
+       AxWin3_RichText_SetBackground   (gMainWindow, 0x000000);
+       AxWin3_RichText_SetFont         (gMainWindow, "#monospace", 10);
+       AxWin3_RichText_SetCursorPos    (gMainWindow, 0, 0);
+       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! \x01""ff0000A red");
+       // </testing>
+
+       AxWin3_ResizeWindow(gMainWindow, 600, 400);
+       AxWin3_MoveWindow(gMainWindow, 50, 50);
+       AxWin3_ShowWindow(gMainWindow, 1);
+       AxWin3_FocusWindow(gMainWindow);
+
+       // Spawn shell
+       giChildStdout = open("/Devices/FIFO/anon", O_RDWR);
+       giChildStdin = open("/Devices/FIFO/anon", O_RDWR);
+
+       {
+                int    fds[] = {giChildStdin, giChildStdout, giChildStdout};
+               const char      *argv[] = {"CLIShell", NULL};
+               _SysSpawn("/Acess/Bin/CLIShell", argv, envp, 3, fds, NULL);
+       }
+
+       // Main loop
+       for( ;; )
+       {
+               fd_set  fds;
+               
+               FD_ZERO(&fds);
+               FD_SET(&fds, giChildStdout);
+               AxWin3_MessageSelect(giChildStdout + 1, &fds);
+               
+               if( FD_ISSET(&fds, giChildStdout) )
+               {
+                       // Read and update screen
+                       char    buf[32];
+                       len = read(giChildStdout, sizeof(buf), buf);
+                       if( len <= 0 )  break;
+                       
+                       //Term_HandleOutput(len, buf);
+               }
+       }
+
+       return 0;
+}
+
+int Term_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated)
+{
+       static int      ctrl_state = 0;
+
+       // Handle modifiers
+       #define _bitset(var,bit,set) do{if(set)var|=1<<(bit);else var&=1<<(bit);}while(0)
+       switch(KeySym)
+       {
+       case KEY_LCTRL:
+               _bitset(ctrl_state, 0, bPress);
+               return 0;
+       case KEY_RCTRL:
+               _bitset(ctrl_state, 0, bPress);
+               return 0;
+       }
+       #undef _bitset
+
+       // Handle shortcuts
+       // - Ctrl-A -- Ctrl-Z
+       if( ctrl_state && KeySym >= KEY_a && KeySym <= KEY_z )
+       {
+               Translated = KeySym - KEY_a + 1;
+       }
+
+       if( Translated )
+       {
+               // Encode and send
+               
+               return 0;
+       }
+       
+       // No translation, look for escape sequences to send
+       switch(KeySym)
+       {
+       case KEY_LEFTARROW:
+               str = "\x1b[D";
+               break;
+       }
+       return 0;
+}
+
+int Term_MouseHandler(tHWND Window, int bPress, int Button, int Row, int Col)
+{
+       return 0;
+}
+
+void Term_HandleOutput(int Len, const char *Buf)
+{
+       // TODO: Handle graphical / accelerated modes
+
+        int    ofs = 0;
+        int    esc_len = 0;
+
+       while( ofs < Len )
+       {
+               esc_len = Term_HandleVT100(Len - ofs, Buf + ofs);
+               if( esc_len < 0 ) {
+                       Display_AddText(-esc_len, Buf + ofs);
+                       esc_len = -esc_len;
+               }
+               Len -= esc_len;
+               ofs += esc_len;
+       }
+}
+
diff --git a/Usermode/Applications/gui_shell_src/vt100.c b/Usermode/Applications/gui_shell_src/vt100.c
new file mode 100644 (file)
index 0000000..51c8016
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Acess GUI Terminal
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - Core
+ */
+#include <string.h>
+#include "include/vt100.h"
+#include "include/display.h"
+
+int Term_HandleVT100(int Len, const char *Buf)
+{
+       const int       max_length = 16;
+       static char     inc_buf[max_length]
+       static int      inc_len = 0;
+
+       if( inc_len > 0 || *Buf == '\x1b' )
+       {
+               memcpy(inc_buf + inc_len, Buf, min(max_length - inc_len, Len));
+               // Handle VT100 (like) escape sequence
+               
+               inc_len = 0;
+               return 1;
+       }
+
+       switch( *Buf )
+       {
+       case '\b':
+               // TODO: Backspace
+               return 1;
+       case '\t':
+               // TODO: tab
+               return 1;
+       case '\n':
+               Display_Newline(1);
+               return 1;
+       case '\r':
+               // TODO: Carriage return
+               return ;
+       }
+
+        int    ret = 0;
+       while( ret < Len )
+       {
+               if( *Buf == '\n' )
+                       break;
+               if( *Buf == '\x1b' )
+                       break;
+               ret ++;
+               Buf ++;
+       }
+       return -ret;
+}

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