Applications/GUI Terminal - Fixed sticky Ctrl/Alt keys, reduced flush rate
[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                                 giCurrentCol ++;
85                         }
86                 }
87         
88                 Display_int_PushString(bytes, UTF8Text);
89
90                 UTF8Text += bytes;
91                 Length -= bytes;
92                 if( Length != 0 )
93                 {
94                         // Next line
95                         giCurrentLinePos = 0;
96                         giCurrentCol = 0;
97                         giCurrentLine ++;
98                 }
99         }
100 }
101
102 void Display_Newline(int bCarriageReturn)
103 {
104 //      Display_Flush();
105
106         // Going down!
107         giCurrentLine ++;
108         if( giCurrentLine == giDisplayLines )
109                 giCurrentLine = 0;
110         if( giCurrentLine == giFirstLine )
111         {
112                 giFirstLine ++;
113                 if(giFirstLine == giDisplayLines)
114                         giFirstLine = 0;
115         }
116         
117         if( bCarriageReturn ) {
118                 giCurrentLinePos = 0;
119                 giCurrentCol = 0;
120         }
121         else {
122                 giCurrentLinePos = 0;
123                  int    i = giCurrentCol;
124                 if( !gasDisplayLines[giCurrentLine] )
125                 {
126                         giCurrentCol = 0;
127                         while(i--)
128                                 Display_AddText(1, " ");
129                 }
130                 else
131                 {
132                         while( i -- )
133                         {
134                                 uint32_t        cp;
135                                 giCurrentLinePos += ReadUTF8(gasDisplayLines[giCurrentLine]+giCurrentLinePos, &cp);
136                                 if( !Unicode_IsPrinting(cp) )
137                                         i ++;
138                         }
139                 }
140         }
141 }
142
143 void Display_SetCursor(int Row, int Col)
144 {
145         UNIMPLIMENTED();
146 }
147
148 void Display_MoveCursor(int RelRow, int RelCol)
149 {
150         if( RelRow < 0 )
151         {
152                 for( ; RelRow < 0; RelRow ++ )
153                 {
154                         uint32_t        cp;
155                         int delta = ReadUTF8Rev(gasDisplayLines[giCurrentLine], giCurrentLinePos, &cp);
156                         if( !Unicode_IsPrinting(cp) )
157                                 RelRow --;
158                         else
159                                 giCurrentCol --;
160                         giCurrentLinePos -= delta;
161                 }
162         }
163         else
164         {
165                 UNIMPLIMENTED();
166         }
167 }
168
169 void Display_ClearLine(int Dir) // 0: All, 1: Forward, -1: Reverse
170 {
171         if( Dir == 0 )
172         {
173                 // Completely clear line
174                 if( gasDisplayLines[giCurrentLine] )
175                         free(gasDisplayLines[giCurrentLine]);
176                 gasDisplayLines[giCurrentLine] = NULL;
177                 gabDisplayLinesDirty[giCurrentLine] = 1;
178         }
179         else if( Dir == 1 )
180         {
181                 // Forward clear (truncate)
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_ClearLines(int Dir)        // 0: All, 1: Forward, -1: Reverse
194 {
195         if( Dir == 0 )
196         {
197                 // Push giDisplayLines worth of empty lines
198                 // Move cursor back up by giDisplayLines
199         }
200         else if( Dir == 1 )
201         {
202                 // Push (giDisplayLines - (giCurrentLine-giFirstDispLine)) and reverse
203         }
204         else if( Dir == -1 )
205         {
206                 // Reverse clear (replace with spaces)
207         }
208         else
209         {
210                 // BUGCHECK
211         }
212 }
213
214 void Display_SetForeground(uint32_t RGB)
215 {
216         char    buf[7+1];
217         sprintf(buf, "\1%06x", RGB&0xFFFFFF);
218         Display_int_PushString(7, buf);
219 }
220
221 void Display_SetBackground(uint32_t RGB)
222 {
223         char    buf[7+1];
224         sprintf(buf, "\2%06x", RGB&0xFFFFFF);
225         Display_int_PushString(7, buf);
226 }
227
228 void Display_Flush(void)
229 {
230          int    i;
231         for( i = 0; i < giDisplayCols; i ++ )
232         {
233                  int    line = (giFirstLine + i) % giDisplayTotalLines;
234                 if( !gabDisplayLinesDirty[line] )
235                         continue;
236                 _SysDebug("Line %i+%i '%s'", giFirstLine, i, gasDisplayLines[line]);
237                 AxWin3_RichText_SendLine(gMainWindow, giFirstLine + i, gasDisplayLines[line] );
238                 gabDisplayLinesDirty[line] = 0;
239         }
240         AxWin3_RichText_SetCursorPos(gMainWindow, giCurrentLine, giCurrentCol);
241 }
242
243 void Display_ShowAltBuffer(int AltBufEnabled)
244 {
245         UNIMPLIMENTED();
246 }
247

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