Merge branch 'master' of git://localhost/acess2
[tpg/acess2.git] / Usermode / Applications / gui_shell_src / main.c
1 /*
2  * Acess GUI Terminal
3  * - By John Hodge (thePowersGang)
4  *
5  * main.c
6  * - Core
7  */
8 #include <axwin3/axwin.h>
9 #include <axwin3/menu.h>
10 #include <axwin3/richtext.h>
11 #include <axwin3/keysyms.h>
12 #include <stdio.h>
13 #include <acess/sys.h>
14 #include "include/display.h"
15 #include "include/vt100.h"
16 #include <string.h>
17 #include <unicode.h>
18
19 // === PROTOTYPES ===
20  int    main(int argc, char *argv[], const char **envp);
21  int    Term_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated);
22  int    Term_MouseHandler(tHWND Window, int bPress, int Button, int Row, int Col);
23 void    Term_HandleOutput(int Len, const char *Buf);
24
25 // === GLOBALS ===
26 tHWND   gMainWindow;
27 tHWND   gMenuWindow;
28  int    giChildStdin;
29  int    giChildStdout;
30
31 // === CODE ===
32 int main(int argc, char *argv[], const char **envp)
33 {
34         AxWin3_Connect(NULL);
35         
36         // --- Build up window
37         gMainWindow = AxWin3_RichText_CreateWindow(NULL, 0);
38         AxWin3_SetWindowTitle(gMainWindow, "Terminal"); // TODO: Update title with other info
39
40         gMenuWindow = AxWin3_Menu_Create(gMainWindow);
41         AxWin3_Menu_AddItem(gMenuWindow, "Copy\tWin+C", NULL, NULL, 0, NULL);
42         AxWin3_Menu_AddItem(gMenuWindow, "Paste\tWin+V", NULL, NULL, 0, NULL);
43         // TODO: Populate menu  
44
45
46         // TODO: Tabs?
47         
48         AxWin3_RichText_SetKeyHandler   (gMainWindow, Term_KeyHandler);
49         AxWin3_RichText_SetMouseHandler (gMainWindow, Term_MouseHandler);
50         AxWin3_RichText_SetDefaultColour(gMainWindow, 0xFFFFFF);
51         AxWin3_RichText_SetBackground   (gMainWindow, 0x000000);
52         AxWin3_RichText_SetFont         (gMainWindow, "#monospace", 10);
53         AxWin3_RichText_SetCursorPos    (gMainWindow, 0, 0);
54         AxWin3_RichText_SetCursorType   (gMainWindow, AXWIN3_RICHTEXT_CURSOR_INV);
55         AxWin3_RichText_SetCursorBlink  (gMainWindow, 1);
56
57         // <testing>
58         AxWin3_RichText_SetLineCount(gMainWindow, 3);
59         AxWin3_RichText_SendLine(gMainWindow, 0, "First line!");
60         AxWin3_RichText_SendLine(gMainWindow, 2, "Third line! \1ff0000A red");
61         // </testing>
62
63         Display_Init(80, 25, 100);
64         AxWin3_ResizeWindow(gMainWindow, 80*8, 25*16);
65         AxWin3_MoveWindow(gMainWindow, 20, 50);
66         AxWin3_ShowWindow(gMainWindow, 1);
67         AxWin3_FocusWindow(gMainWindow);
68
69         // Spawn shell
70         giChildStdin = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE);
71         giChildStdout = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE);
72         if( giChildStdout == -1 || giChildStdin == -1 ) {
73                 perror("Oh, fsck");
74                 _SysDebug("out,in = %i,%i", giChildStdout, giChildStdin);
75                 return -1;
76         }
77
78         {
79                  int    fds[] = {giChildStdin, giChildStdout, giChildStdout};
80                 const char      *argv[] = {"CLIShell", NULL};
81                 int pid = _SysSpawn("/Acess/Bin/CLIShell", argv, envp, 3, fds, NULL);
82                 if( pid < 0 )
83                         _SysDebug("ERROR: Shell spawn failed");
84         }
85
86         // Main loop
87         for( ;; )
88         {
89                 fd_set  fds;
90                 
91                 FD_ZERO(&fds);
92                 FD_SET(giChildStdout, &fds);
93                 AxWin3_MessageSelect(giChildStdout + 1, &fds);
94                 
95                 if( FD_ISSET(giChildStdout, &fds) )
96                 {
97                         _SysDebug("Activity on child stdout");
98                         // Read and update screen
99                         char    buf[128];
100                         int len = _SysRead(giChildStdout, buf, sizeof(buf));
101                         if( len <= 0 )  break;
102                         
103                         Term_HandleOutput(len, buf);
104                 }
105         }
106
107         return 0;
108 }
109
110 int Term_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated)
111 {
112         static int      ctrl_state = 0;
113
114         // Handle modifiers
115         #define _bitset(var,bit,set) do{if(set)var|=1<<(bit);else var&=~(1<<(bit));}while(0)
116         switch(KeySym)
117         {
118         case KEYSYM_LEFTCTRL:
119                 _bitset(ctrl_state, 0, bPress!=0);
120                 return 0;
121         case KEYSYM_RIGHTCTRL:
122                 _bitset(ctrl_state, 1, bPress!=0);
123                 return 0;
124         }
125         #undef _bitset
126
127         // Handle shortcuts
128         // - Ctrl-A -- Ctrl-Z
129         if( ctrl_state && KeySym >= KEYSYM_a && KeySym <= KEYSYM_z )
130         {
131                 Translated = KeySym - KEYSYM_a + 1;
132                 _SysDebug("Ctrl-%c: KS %x => Trans %x", 'A'+(KeySym-KEYSYM_a), KeySym, Translated);
133         }
134
135         // == 2 :: FIRE
136         if( bPress == 2 )
137         {
138                 if( Translated )
139                 {
140                         char    buf[6];
141                          int    len;
142                         
143                         // Encode and send
144                         len = WriteUTF8(buf, Translated);
145                         
146                         _SysDebug("Keystroke %x:%x translated to '%.*s'", KeySym, Translated, len, buf);
147                         _SysWrite(giChildStdin, buf, len);
148                         
149                         return 0;
150                 }
151                 
152                 // No translation, look for escape sequences to send
153                 const char *str = NULL;
154                 switch(KeySym)
155                 {
156                 case KEYSYM_LEFTARROW:
157                         str = "\x1b[D";
158                         break;
159                 }
160                 if( str )
161                 {
162                         _SysWrite(giChildStdin, str, strlen(str));
163                 }
164         }
165         return 0;
166 }
167
168 int Term_MouseHandler(tHWND Window, int bPress, int Button, int Row, int Col)
169 {
170         return 0;
171 }
172
173 void Term_HandleOutput(int Len, const char *Buf)
174 {
175         // TODO: Handle graphical / accelerated modes
176
177          int    ofs = 0;
178          int    esc_len = 0;
179
180         while( ofs < Len )
181         {
182                 esc_len = Term_HandleVT100(Len - ofs, Buf + ofs);
183                 if( esc_len < 0 ) {
184                         Display_AddText(-esc_len, Buf + ofs);
185                         esc_len = -esc_len;
186                 }
187                 ofs += esc_len;
188                 //_SysDebug("Len = %i, ofs = %i", Len, ofs);
189         }
190         
191         Display_Flush();
192 }
193

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