Kernel/VTerm - Fix doing full redraw on every string
[tpg/acess2.git] / KernelLand / Kernel / drv / vterm_vt100.c
1 /*
2  * Acess2 Kernel
3  * - By John Hodge (thePowersGang)
4  *
5  * drv/vterm_vt100.c
6  * - Virtual Terminal - VT100 (Kinda) Emulation
7  */
8 #define DEBUG   0
9 #include "vterm.h"
10
11 #define sTerminal       sVTerm
12 #include "../../../Usermode/Applications/gui_terminal_src/vt100.c"
13
14 void *Display_GetTermState(tTerminal *Term) {
15         return Term->VT100Info;
16 }
17 void Display_SetTermState(tTerminal *Term, void *State) {
18         Term->VT100Info = State;
19 }
20
21 void Display_SendInput(tTerminal *Term, const char *String)
22 {
23         PTY_SendInput(Term->PTY, String, strlen(String));
24 }
25
26 void Display_AddText(tTerminal *Term, size_t Length, const char *UTF8Text)
27 {
28         LOG("'%*C'", Length, UTF8Text);
29         VT_int_PutRawString(Term, (const void*)UTF8Text, Length);
30 }
31 void Display_Newline(tTerminal *Term, bool bCarriageReturn)
32 {
33         LOG("");
34         VT_int_PutChar(Term, '\n');
35 }
36 void Display_SetScrollArea(tTerminal *Term, int Start, int Count)
37 {
38         LOG("(%i,+%i)", Start, Count);
39         Term->ScrollTop = Start;
40         Term->ScrollHeight = Count;
41 }
42 void Display_ScrollDown(tTerminal *Term, int CountDown)
43 {
44         LOG("(%i)", CountDown);
45         VT_int_UpdateScreen(Term, 0);
46         if( Term->Flags & VT_FLAG_ALTBUF )
47                 VT_int_ScrollText(Term, -CountDown);
48         else
49         {
50                 if(Term->ViewTopRow + CountDown < 0)
51                         return ;
52                 if(Term->ViewTopRow + CountDown  > Term->TextHeight * (giVT_Scrollback + 1))
53                         return ;
54                 
55                 Term->ViewTopRow += CountDown;
56         }
57 }
58 void Display_SetCursor(tTerminal *Term, int Row, int Col)
59 {
60         LOG("(R%i,C%i)", Row, Col);
61         VT_int_UpdateScreen(Term, 0);
62          int    maxrows = VT_int_GetBufferRows(Term);
63         ASSERTCR( Row, >=, 0, );
64         ASSERTCR( Row, <, maxrows, );
65         ASSERTCR( Col, >=, 0, );
66         ASSERTCR( Col, <, Term->TextWidth, );
67         VT_int_GetWritePosPtr(Term)->Row = Row;
68         VT_int_GetWritePosPtr(Term)->Col = Col;
69 }
70 void Display_MoveCursor(tTerminal *Term, int RelRow, int RelCol)
71 {
72         LOG("(R+%i,C+%i)", RelRow, RelCol);
73         tVT_Pos *wrpos = VT_int_GetWritePosPtr(Term);
74
75         // TODO: Support scrolling if cursor goes offscreen
76         // if( bScrollIfNeeded )
77         //      Display_ScrollDown(extra);
78         // else
79         //      clip
80
81         if( RelCol != 0 )
82         {
83                 // 
84                 if( RelCol < 0 )
85                 {
86                          int    max = wrpos->Col;
87                         if( RelCol < -max )
88                                 RelCol = -max;
89                 }
90                 else
91                 {
92                         size_t  max = Term->TextWidth - wrpos->Col - 1;
93                         if(RelCol > max)
94                                 RelCol = max;
95                 }
96                 wrpos->Col += RelCol;
97         }
98         if( RelRow != 0 )
99         {
100                  int    currow = wrpos->Row;
101                  int    maxrows = VT_int_GetBufferRows(Term);
102                 if( RelRow < 0 )
103                 {
104                         if( RelRow < -currow )
105                                 RelRow = -currow;
106                 }
107                 else
108                 {
109                         if( currow + RelRow > maxrows-1 )
110                                 RelRow = maxrows-1 - currow;
111                 }
112                 wrpos->Row += RelRow;
113         }
114         LOG("=(R%i,C%i)", wrpos->Row, wrpos->Col);
115 }
116 void Display_SaveCursor(tTerminal *Term)
117 {
118         Term->SavedWritePos = *VT_int_GetWritePosPtr(Term);
119         LOG("Saved = %i", Term->SavedWritePos);
120 }
121 void Display_RestoreCursor(tTerminal *Term)
122 {
123         size_t  maxrow = VT_int_GetBufferRows(Term);
124         tVT_Pos *wrpos = VT_int_GetWritePosPtr(Term);
125         *wrpos = Term->SavedWritePos;
126         if(wrpos->Row >= maxrow)
127                 wrpos->Row = maxrow-1;
128         if(wrpos->Col >= Term->TextWidth )
129                 wrpos->Col = Term->TextWidth-1;
130         LOG("Restored (R%i,C%i)", wrpos->Row, wrpos->Col);
131 }
132 // 0: All, 1: Forward, -1: Reverse
133 void Display_ClearLine(tTerminal *Term, int Dir)
134 {
135         const tVT_Pos   *wrpos = VT_int_GetWritePosPtr(Term);
136
137         LOG("(Dir=%i)", Dir);
138
139         // Erase all
140         if( Dir == 0 ) {
141                 VT_int_ClearLine(Term, wrpos->Row);
142                 VT_int_UpdateScreen(Term, 0);
143         }
144         // Erase to right
145         else if( Dir == 1 ) {
146                 VT_int_ClearInLine(Term, wrpos->Row, wrpos->Col, Term->TextWidth);
147                 VT_int_UpdateScreen(Term, 0);
148         }
149         // Erase to left
150         else if( Dir == -1 ) {
151                 VT_int_ClearInLine(Term, wrpos->Row, 0, wrpos->Col);
152                 VT_int_UpdateScreen(Term, 0);
153         }
154         else {
155                 // ERROR!
156                 ASSERTC(Dir, >=, -1);
157                 ASSERTC(Dir, <=, 1);
158         }
159 }
160 void Display_ClearLines(tTerminal *Term, int Dir)
161 {
162         LOG("(Dir=%i)", Dir);   
163         tVT_Pos *wrpos = VT_int_GetWritePosPtr(Term);
164         size_t  height = VT_int_GetBufferRows(Term);
165         
166         // All
167         if( Dir == 0 ) {
168                 
169                 if( !(Term->Flags & VT_FLAG_ALTBUF) ) {
170                         Term->ViewTopRow = 0;
171                 }
172                 int count = height;
173                 while( count -- )
174                         VT_int_ClearLine(Term, count);
175                 wrpos->Col = 0;
176                 wrpos->Row = 0;
177                 VT_int_UpdateScreen(Term, 1);
178         }
179         // Downwards
180         else if( Dir == 1 ) {
181                 for( int row = wrpos->Row; row < height; row ++ )
182                         VT_int_ClearLine(Term, row);
183                 VT_int_UpdateScreen(Term, 1);
184         }
185         // Upwards
186         else if( Dir == -1 ) {
187                 for( int row = 0; row < wrpos->Row; row ++ )
188                         VT_int_ClearLine(Term, row);
189                 VT_int_UpdateScreen(Term, 1);
190         }
191         else {
192                 // ERROR!
193                 ASSERTC(Dir, >=, -1);
194                 ASSERTC(Dir, <=, 1);
195         }
196 }
197 void Display_ResetAttributes(tTerminal *Term)
198 {
199         LOG("");        
200         Term->CurColour = DEFAULT_COLOUR;
201 }
202 void Display_SetForeground(tTerminal *Term, uint32_t RGB)
203 {
204         LOG("(%06x)", RGB);
205         Term->CurColour &= 0x8000FFFF;
206         Term->CurColour |= (Uint32)VT_Colour24to12(RGB) << 16;
207         
208 }
209 void Display_SetBackground(tTerminal *Term, uint32_t RGB)
210 {
211         LOG("(%06x)", RGB);
212         Term->CurColour &= 0xFFFF8000;
213         Term->CurColour |= (Uint32)VT_Colour24to12(RGB) <<  0;
214 }
215 void Display_Flush(tTerminal *Term)
216 {
217         LOG("");
218         VT_int_UpdateScreen(Term, 0);
219 }
220 void Display_ShowAltBuffer(tTerminal *Term, bool AltBufEnabled)
221 {
222         LOG("(%B)", AltBufEnabled);
223         VT_int_ToggleAltBuffer(Term, AltBufEnabled);
224 }
225 void Display_SetTitle(tTerminal *Term, const char *Title)
226 {
227         // ignore
228 }
229

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