Kernel/VTerm - VT100 emulation fixes exposed by dropbear+irssi
[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   1
9 #include "vterm.h"
10
11 #define sTerminal       sVTerm
12 #include "../../../Usermode/Applications/gui_terminal_src/vt100.c"
13
14 void Display_AddText(tTerminal *Term, size_t Length, const char *UTF8Text)
15 {
16         LOG("'%.*s'", Length, UTF8Text);
17         VT_int_PutRawString(Term, (const void*)UTF8Text, Length);
18 }
19 void Display_Newline(tTerminal *Term, bool bCarriageReturn)
20 {
21         LOG("");
22         VT_int_PutChar(Term, '\n');
23 }
24 void Display_SetScrollArea(tTerminal *Term, int Start, int Count)
25 {
26         LOG("(%i,+%i)", Start, Count);
27         Term->ScrollTop = Start;
28         Term->ScrollHeight = Count;
29 }
30 void Display_ScrollDown(tTerminal *Term, int CountDown)
31 {
32         LOG("(%i)", CountDown);
33         VT_int_UpdateScreen(Term, 0);
34         if( Term->Flags & VT_FLAG_ALTBUF )
35                 VT_int_ScrollText(Term, CountDown);
36         else
37         {
38                 if(Term->ViewPos/Term->TextWidth + CountDown < 0)
39                         return ;
40                 if(Term->ViewPos/Term->TextWidth + CountDown  > Term->TextHeight * (giVT_Scrollback + 1))
41                         return ;
42                 
43                 Term->ViewPos += Term->TextWidth * CountDown;
44         }
45 }
46 void Display_SetCursor(tTerminal *Term, int Row, int Col)
47 {
48         LOG("(R%i,C%i)", Row, Col);
49         VT_int_UpdateScreen(Term, 0);
50          int    maxrows = ((Term->Flags & VT_FLAG_ALTBUF) ? 1 : (giVT_Scrollback+1))*Term->TextHeight;
51         ASSERTCR( Row, >=, 0, );
52         ASSERTCR( Row, <, maxrows, );
53         ASSERTCR( Col, >=, 0, );
54         ASSERTCR( Col, <, Term->TextWidth, );
55         *(Term->Flags & VT_FLAG_ALTBUF ? &Term->AltWritePos : &Term->WritePos) = Row*Term->TextWidth + Col;
56 }
57 void Display_MoveCursor(tTerminal *Term, int RelRow, int RelCol)
58 {
59         LOG("(R+%i,C+%i)", RelRow, RelCol);
60         int     *wrpos = (Term->Flags & VT_FLAG_ALTBUF ? &Term->AltWritePos : &Term->WritePos);
61
62         if( RelCol != 0 )
63         {
64                 // 
65                 if( RelCol < 0 )
66                 {
67                          int    avail = *wrpos % Term->TextWidth;
68                         if( RelCol < -avail )
69                                 RelCol = -avail;
70                 }
71                 else
72                 {
73                         size_t  avail = Term->TextWidth - (*wrpos % Term->TextWidth);
74                         if(RelCol > avail)
75                                 RelCol = avail;
76                 }
77                 *wrpos += RelCol;
78         }
79         if( RelRow != 0 )
80         {
81                  int    currow = *wrpos / Term->TextWidth;
82                  int    maxrows = ((Term->Flags & VT_FLAG_ALTBUF) ? 1 : (giVT_Scrollback+1))*Term->TextHeight;
83                 if( RelRow < 0 )
84                 {
85                         if( RelRow < -currow )
86                                 RelRow = -currow;
87                 }
88                 else
89                 {
90                         if( currow + RelRow > maxrows-1 )
91                                 RelRow = maxrows-1 - currow;
92                 }
93                 *wrpos += RelRow*Term->TextWidth;
94         }
95         LOG("=(R%i,C%i)", *wrpos / Term->TextWidth, *wrpos % Term->TextWidth);
96 }
97 void Display_SaveCursor(tTerminal *Term)
98 {
99         Term->SavedWritePos = (Term->Flags & VT_FLAG_ALTBUF) ? Term->AltWritePos : Term->WritePos;
100         LOG("Saved = %i", Term->SavedWritePos);
101 }
102 void Display_RestoreCursor(tTerminal *Term)
103 {
104          int    max = ((Term->Flags & VT_FLAG_ALTBUF) ? 1 : (giVT_Scrollback+1))*Term->TextHeight * Term->TextWidth;
105          int    *wrpos = ((Term->Flags & VT_FLAG_ALTBUF) ? &Term->AltWritePos : &Term->WritePos);
106         if( Term->SavedWritePos >= max )
107                 *wrpos = max-1;
108         else
109                 *wrpos = Term->SavedWritePos;
110         LOG("Restored %i", *wrpos);
111 }
112 // 0: All, 1: Forward, -1: Reverse
113 void Display_ClearLine(tTerminal *Term, int Dir)
114 {
115          int    *wrpos = (Term->Flags & VT_FLAG_ALTBUF ? &Term->AltWritePos : &Term->WritePos);
116         tVT_Char        *buffer = (Term->Flags & VT_FLAG_ALTBUF ? Term->AltBuf : Term->Text);
117
118         LOG("(Dir=%i)", Dir);   
119
120         // Erase all
121         if( Dir == 0 ) {
122                 VT_int_ClearLine(Term, *wrpos / Term->Width);
123                 VT_int_UpdateScreen(Term, 0);
124         }
125         // Erase to right
126         else if( Dir == 1 ) {
127                 int max = Term->Width - *wrpos % Term->Width;
128                 for( int i = 0; i < max; i ++ )
129                         buffer[*wrpos+i].Ch = 0;
130                 VT_int_UpdateScreen(Term, 0);
131         }
132         // Erase to left
133         else if( Dir == -1 ) {
134                 int start = *wrpos - *wrpos % Term->Width;
135                 for( int i = start; i < *wrpos; i ++ )
136                         buffer[i].Ch = 0;
137                 VT_int_UpdateScreen(Term, 0);
138         }
139         else {
140                 // ERROR!
141                 ASSERTC(Dir, >=, -1);
142                 ASSERTC(Dir, <=, 1);
143         }
144 }
145 void Display_ClearLines(tTerminal *Term, int Dir)
146 {
147         LOG("(Dir=%i)", Dir);   
148          int    *wrpos = (Term->Flags & VT_FLAG_ALTBUF ? &Term->AltWritePos : &Term->WritePos);
149         tVT_Char        *buffer = (Term->Flags & VT_FLAG_ALTBUF ? Term->AltBuf : Term->Text);
150         
151         // All
152         if( Dir == 0 ) {
153                 int count;
154                 
155                 if( Term->Flags & VT_FLAG_ALTBUF ) {
156                         count = Term->TextHeight;
157                 }
158                 else {
159                         count = Term->TextHeight * (giVT_Scrollback + 1);
160                         Term->ViewPos = 0;
161                 }
162                 while( count -- )
163                         VT_int_ClearLine(Term, count);
164                 *wrpos = 0;
165                 VT_int_UpdateScreen(Term, 1);
166         }
167         // Downwards
168         else if( Dir == 1 ) {
169                 Log_Warning("VTerm", "TODO: ClearLines Down");
170         }
171         // Upwards
172         else if( Dir == -1 ) {
173                 Log_Warning("VTerm", "TODO: ClearLines Up");
174         }
175         else {
176                 // ERROR!
177                 ASSERTC(Dir, >=, -1);
178                 ASSERTC(Dir, <=, 1);
179         }
180 }
181 void Display_ResetAttributes(tTerminal *Term)
182 {
183         LOG("");        
184         Term->CurColour = DEFAULT_COLOUR;
185 }
186 void Display_SetForeground(tTerminal *Term, uint32_t RGB)
187 {
188         LOG("(%06x)", RGB);
189         Term->CurColour &= 0x8000FFFF;
190         Term->CurColour |= (Uint32)VT_Colour24to12(RGB) << 16;
191         
192 }
193 void Display_SetBackground(tTerminal *Term, uint32_t RGB)
194 {
195         LOG("(%06x)", RGB);
196         Term->CurColour &= 0xFFFF8000;
197         Term->CurColour |= (Uint32)VT_Colour24to12(RGB) <<  0;
198 }
199 void Display_Flush(tTerminal *Term)
200 {
201         LOG("");
202         VT_int_UpdateScreen(Term, 0);
203 }
204 void Display_ShowAltBuffer(tTerminal *Term, bool AltBufEnabled)
205 {
206         LOG("(%B)", AltBufEnabled);
207         VT_int_ToggleAltBuffer(Term, AltBufEnabled);
208 }
209

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