Usermode/GUITerminal - Text colouring and cursor
[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         AxWin3_RichText_SetLineCount(gMainWindow, Lines+ExtraScrollbackLines);
47         AxWin3_RichText_SetCursorType(gMainWindow, 1);  // TODO: enum
48 }
49
50 void Display_int_PushString(int Length, const char *Text)
51 {
52         _SysDebug("Line %i += %i '%*C'", giCurrentLine, Length, Length, Text);
53         if( !gasDisplayLines[giCurrentLine] || giCurrentLinePos + Length >= gaiDisplayLineSizes[giCurrentLine] )
54         {
55                  int    reqsize = giCurrentLinePos + Length;
56                 gaiDisplayLineSizes[giCurrentLine] = (reqsize + 32-1) & ~(32-1);
57                 void *tmp = realloc(gasDisplayLines[giCurrentLine], gaiDisplayLineSizes[giCurrentLine]);
58                 if( !tmp )      perror("Display_AddText - realloc");
59                 gasDisplayLines[giCurrentLine] = tmp;
60         }
61
62         memcpy(gasDisplayLines[giCurrentLine]+giCurrentLinePos, Text, Length);
63         gabDisplayLinesDirty[giCurrentLine] = 1;
64         gasDisplayLines[giCurrentLine][giCurrentLinePos+Length] = 0;
65         giCurrentLinePos += Length;
66         
67 }
68
69 void Display_AddText(int Length, const char *UTF8Text)
70 {
71         _SysDebug("%i '%.*s'", Length, Length, UTF8Text);
72         // Copy as many characters (not bytes, have to trim off the last char) as we can to the current line
73         // - then roll over to the next line
74         while( Length > 0 )
75         {
76                  int    space = giDisplayCols - giCurrentCol;
77                  int    bytes = 0;
78                 while( space && bytes < Length )
79                 {
80                         uint32_t        cp;
81                         bytes += ReadUTF8(UTF8Text+bytes, &cp);
82                         if( Unicode_IsPrinting(cp) )
83                                 space --;
84                 }
85         
86                 Display_int_PushString(bytes, UTF8Text);
87
88                 UTF8Text += bytes;
89                 _SysDebug("Length(%i) -= bytes(%i)", Length, bytes);
90                 Length -= bytes;
91                 if( Length != 0 )
92                 {
93                         // Next line
94                         giCurrentLinePos = 0;
95                         giCurrentCol = 0;
96                         giCurrentLine ++;
97                 }
98         }
99 }
100
101 void Display_Newline(int bCarriageReturn)
102 {
103         Display_Flush();
104
105         // Going down!
106         giCurrentLine ++;
107         if( giCurrentLine == giDisplayLines )
108                 giCurrentLine = 0;
109         if( giCurrentLine == giFirstLine )
110         {
111                 giFirstLine ++;
112                 if(giFirstLine == giDisplayLines)
113                         giFirstLine = 0;
114         }
115         
116         if( bCarriageReturn ) {
117                 giCurrentLinePos = 0;
118                 giCurrentCol = 0;
119         }
120         else {
121                 giCurrentLinePos = 0;
122                  int    i = giCurrentCol;
123                 if( !gasDisplayLines[giCurrentLine] )
124                 {
125                         giCurrentCol = 0;
126                         while(i--)
127                                 Display_AddText(1, " ");
128                 }
129                 else
130                 {
131                         while( i -- )
132                         {
133                                 uint32_t        cp;
134                                 giCurrentLinePos += ReadUTF8(gasDisplayLines[giCurrentLine]+giCurrentLinePos, &cp);
135                                 if( !Unicode_IsPrinting(cp) )
136                                         i ++;
137                         }
138                 }
139         }
140 }
141
142 void Display_SetCursor(int Row, int Col)
143 {
144         UNIMPLIMENTED();
145 }
146
147 void Display_MoveCursor(int RelRow, int RelCol)
148 {
149         UNIMPLIMENTED();
150 }
151
152 void Display_ClearLine(int Dir) // 0: All, 1: Forward, -1: Reverse
153 {
154         if( Dir == 0 )
155         {
156                 // Completely clear line
157                 if( gasDisplayLines[giCurrentLine] )
158                         free(gasDisplayLines[giCurrentLine]);
159                 gasDisplayLines[giCurrentLine] = NULL;
160                 gabDisplayLinesDirty[giCurrentLine] = 1;
161         }
162         else if( Dir == 1 )
163         {
164                 // Forward clear (truncate)
165         }
166         else if( Dir == -1 )
167         {
168                 // Reverse clear (replace with spaces)
169         }
170         else
171         {
172                 // BUGCHECK
173         }
174 }
175
176 void Display_ClearLines(int Dir)        // 0: All, 1: Forward, -1: Reverse
177 {
178         if( Dir == 0 )
179         {
180                 // Push giDisplayLines worth of empty lines
181                 // Move cursor back up by giDisplayLines
182         }
183         else if( Dir == 1 )
184         {
185                 // Push (giDisplayLines - (giCurrentLine-giFirstDispLine)) and reverse
186         }
187         else if( Dir == -1 )
188         {
189                 // Reverse clear (replace with spaces)
190         }
191         else
192         {
193                 // BUGCHECK
194         }
195 }
196
197 void Display_SetForeground(uint32_t RGB)
198 {
199         char    buf[7+1];
200         sprintf(buf, "\1%06x", RGB&0xFFFFFF);
201         Display_int_PushString(7, buf);
202 }
203
204 void Display_SetBackground(uint32_t RGB)
205 {
206         char    buf[7+1];
207         sprintf(buf, "\2%06x", RGB&0xFFFFFF);
208         Display_int_PushString(7, buf);
209 }
210
211 void Display_Flush(void)
212 {
213          int    i;
214         for( i = 0; i < giDisplayCols; i ++ )
215         {
216                  int    line = (giFirstLine + i) % giDisplayTotalLines;
217                 if( !gabDisplayLinesDirty[line] )
218                         continue;
219                 _SysDebug("Line %i+%i '%s'", giFirstLine, i, gasDisplayLines[line]);
220                 AxWin3_RichText_SendLine(gMainWindow, giFirstLine + i, gasDisplayLines[line] );
221                 gabDisplayLinesDirty[line] = 0;
222         }
223         
224         // force redraw?
225         AxWin3_RichText_SetCursorPos(gMainWindow, giCurrentLine, giCurrentCol);
226 }
227
228 void Display_ShowAltBuffer(int AltBufEnabled)
229 {
230         UNIMPLIMENTED();
231 }
232

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