Usermode/GUITerminal - Now can show shell
[tpg/acess2.git] / Usermode / Applications / gui_shell_src / display.c
1 /*
2  * Acess GUI Terminal
3  * - By John Hodge (thePowersGang)
4  *
5  * display.c
6  * - Abstract display manipulation methods
7  */
8 #include "include/display.h"
9 #include <acess/sys.h>  // _SysDebug
10 #include <stdlib.h>     // exit
11 #include <string.h>
12 #include <unicode.h>
13 #include <stdio.h>
14 #include <axwin3/axwin.h>
15 #include <axwin3/richtext.h>
16
17 #define UNIMPLIMENTED() do{_SysDebug("UNIMPLIMENTED %s", __func__); exit(-1);}while(0)
18
19 // === EXTERN ==
20 extern tHWND    gMainWindow;
21
22 // === GLOBALS ===
23  int    giDisplayCols;
24  int    giDisplayLines;
25  int    giDisplayTotalLines;
26  int    giDisplayBufSize;
27  int    giCurrentLine;
28  int    giCurrentLinePos;       // byte offset, not column
29  int    giCurrentCol;
30  int    giFirstDispLine;        // First displayed line
31  int    giFirstLine;    // Ring buffer start
32 char    **gasDisplayLines;
33  int    *gaiDisplayLineSizes;
34 char    *gabDisplayLinesDirty;
35
36 // === CODE ===
37 void Display_Init(int Cols, int Lines, int ExtraScrollbackLines)
38 {
39         giDisplayCols = Cols;
40         giDisplayLines = Lines;
41         giDisplayTotalLines = Lines + ExtraScrollbackLines;
42         gasDisplayLines = calloc( sizeof(char*), (Lines + ExtraScrollbackLines) );
43         gaiDisplayLineSizes = calloc( sizeof(int), (Lines + ExtraScrollbackLines) );
44         gabDisplayLinesDirty = calloc( sizeof(char), (Lines + ExtraScrollbackLines) );
45 }
46
47 void Display_int_PushString(int Length, const char *Text)
48 {
49         _SysDebug("Line %i += %i '%*C'", giCurrentLine, Length, Length, Text);
50         if( !gasDisplayLines[giCurrentLine] || giCurrentLinePos + Length >= gaiDisplayLineSizes[giCurrentLine] )
51         {
52                  int    reqsize = giCurrentLinePos + Length;
53                 gaiDisplayLineSizes[giCurrentLine] = (reqsize + 32-1) & ~(32-1);
54                 void *tmp = realloc(gasDisplayLines[giCurrentLine], gaiDisplayLineSizes[giCurrentLine]);
55                 if( !tmp )      perror("Display_AddText - realloc");
56                 gasDisplayLines[giCurrentLine] = tmp;
57         }
58
59         memcpy(gasDisplayLines[giCurrentLine]+giCurrentLinePos, Text, Length);
60         gabDisplayLinesDirty[giCurrentLine] = 1;
61         gasDisplayLines[giCurrentLine][giCurrentLinePos+Length] = 0;
62         
63 }
64
65 void Display_AddText(int Length, const char *UTF8Text)
66 {
67         _SysDebug("%i '%.*s'", Length, Length, UTF8Text);
68         // Copy as many characters (not bytes, have to trim off the last char) as we can to the current line
69         // - then roll over to the next line
70         while( Length > 0 )
71         {
72                  int    space = giDisplayCols - giCurrentCol;
73                  int    bytes = 0;
74                 while( space && bytes < Length )
75                 {
76                         uint32_t        cp;
77                         bytes += ReadUTF8(UTF8Text+bytes, &cp);
78                         if( Unicode_IsPrinting(cp) )
79                                 space --;
80                 }
81         
82                 Display_int_PushString(bytes, UTF8Text);
83
84                 UTF8Text += bytes;
85                 _SysDebug("Length(%i) -= bytes(%i)", Length, bytes);
86                 Length -= bytes;
87                 if( Length != 0 )
88                 {
89                         // Next line
90                         giCurrentLinePos = 0;
91                         giCurrentCol = 0;
92                         giCurrentLine ++;
93                 }
94         }
95 }
96
97 void Display_Newline(int bCarriageReturn)
98 {
99         Display_Flush();
100
101         // Going down!
102         giCurrentLine ++;
103         if( giCurrentLine == giDisplayLines )
104                 giCurrentLine = 0;
105         if( giCurrentLine == giFirstLine )
106         {
107                 giFirstLine ++;
108                 if(giFirstLine == giDisplayLines)
109                         giFirstLine = 0;
110         }
111         
112         if( bCarriageReturn ) {
113                 giCurrentLinePos = 0;
114                 giCurrentCol = 0;
115         }
116         else {
117                 giCurrentLinePos = 0;
118                  int    i = giCurrentCol;
119                 if( !gasDisplayLines[giCurrentLine] )
120                 {
121                         giCurrentCol = 0;
122                         while(i--)
123                                 Display_AddText(1, " ");
124                 }
125                 else
126                 {
127                         while( i -- )
128                         {
129                                 uint32_t        cp;
130                                 giCurrentLinePos += ReadUTF8(gasDisplayLines[giCurrentLine]+giCurrentLinePos, &cp);
131                                 if( !Unicode_IsPrinting(cp) )
132                                         i ++;
133                         }
134                 }
135         }
136 }
137
138 void Display_SetCursor(int Row, int Col)
139 {
140         UNIMPLIMENTED();
141 }
142
143 void Display_MoveCursor(int RelRow, int RelCol)
144 {
145         UNIMPLIMENTED();
146 }
147
148 void Display_ClearLine(int Dir) // 0: All, 1: Forward, -1: Reverse
149 {
150         if( Dir == 0 )
151         {
152                 // Completely clear line
153                 if( gasDisplayLines[giCurrentLine] )
154                         free(gasDisplayLines[giCurrentLine]);
155                 gasDisplayLines[giCurrentLine] = NULL;
156                 gabDisplayLinesDirty[giCurrentLine] = 1;
157         }
158         else if( Dir == 1 )
159         {
160                 // Forward clear (truncate)
161         }
162         else if( Dir == -1 )
163         {
164                 // Reverse clear (replace with spaces)
165         }
166         else
167         {
168                 // BUGCHECK
169         }
170 }
171
172 void Display_ClearLines(int Dir)        // 0: All, 1: Forward, -1: Reverse
173 {
174         if( Dir == 0 )
175         {
176                 // Push giDisplayLines worth of empty lines
177                 // Move cursor back up by giDisplayLines
178         }
179         else if( Dir == 1 )
180         {
181                 // Push (giDisplayLines - (giCurrentLine-giFirstDispLine)) and reverse
182         }
183         else if( Dir == -1 )
184         {
185                 // Reverse clear (replace with spaces)
186         }
187         else
188         {
189                 // BUGCHECK
190         }
191 }
192
193 void Display_SetForeground(uint32_t RGB)
194 {
195         UNIMPLIMENTED();
196 }
197
198 void Display_SetBackground(uint32_t RGB)
199 {
200         UNIMPLIMENTED();
201 }
202
203 void Display_Flush(void)
204 {
205          int    i;
206         for( i = 0; i < giDisplayCols; i ++ )
207         {
208                  int    line = (giFirstLine + i) % giDisplayTotalLines;
209                 if( !gabDisplayLinesDirty[line] )
210                         continue;
211                 _SysDebug("Line %i+%i '%s'", giFirstLine, i, gasDisplayLines[line]);
212                 AxWin3_RichText_SendLine(gMainWindow, giFirstLine + i, gasDisplayLines[line] );
213                 gabDisplayLinesDirty[line] = 0;
214         }
215         
216         // force redraw?
217         AxWin3_FocusWindow(gMainWindow);
218 }
219
220 void Display_ShowAltBuffer(int AltBufEnabled)
221 {
222         UNIMPLIMENTED();
223 }
224

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