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

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