Kernel/VTerm - "Fix" wrapping issue in VTerm (why was old behavior there?)
[tpg/acess2.git] / KernelLand / Kernel / drv / vterm_output.c
1 /*
2  * Acess2 Kernel
3  * - By John Hodge (thePowersGang)
4  *
5  * drv/vterm_input.c
6  * - Virtual Terminal - Input code
7  */
8 #define DEBUG   0
9 #include "vterm.h"
10 #include <api_drv_video.h>
11
12 // === CODE ===
13 /**
14  * \fn void VT_InitOutput()
15  * \brief Initialise Video Output
16  */
17 void VT_InitOutput()
18 {
19         giVT_OutputDevHandle = VFS_Open(gsVT_OutputDevice, VFS_OPENFLAG_WRITE);
20         if(giVT_OutputDevHandle == -1) {
21                 Log_Warning("VTerm", "Oh F**k, I can't open the video device '%s'", gsVT_OutputDevice);
22                 return ;
23         }
24         VT_SetResolution( giVT_RealWidth, giVT_RealHeight );
25         VT_SetTerminal( 0 );
26         VT_SetMode( VIDEO_BUFFMT_TEXT );
27         LOG("VTerm output initialised");
28 }
29
30 /**
31  * \brief Set video output buffer mode
32  */
33 void VT_SetMode(int Mode)
34 {
35         VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &Mode );
36 }
37
38 /**
39  * \fn void VT_int_ScrollFramebuffer( tVTerm *Term, int Count )
40  * \note Scrolls the framebuffer down by \a Count text lines
41  */
42 void VT_int_ScrollFramebuffer( tVTerm *Term, int Count )
43 {
44          int    tmp;
45         struct {
46                 Uint8   Op;
47                 Uint16  DstX, DstY;
48                 Uint16  SrcX, SrcY;
49                 Uint16  W, H;
50         } PACKED        buf;
51         
52         // Only update if this is the current terminal
53         if( Term != gpVT_CurTerm )      return;
54         
55         ENTER("pTerm iCount",
56                 Term, Count);
57         
58         if( Count > Term->ScrollHeight )        Count = Term->ScrollHeight;
59         if( Count < -Term->ScrollHeight )       Count = -Term->ScrollHeight;
60         LOG("Count = %i", Count);
61         
62         // Switch to 2D Command Stream
63         tmp = VIDEO_BUFFMT_2DSTREAM;
64         VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &tmp);
65         
66         // BLIT to 0,0 from 0,giVT_CharHeight
67         buf.Op = VIDEO_2DOP_BLIT;
68         buf.SrcX = 0;   buf.DstX = 0;
69         // TODO: Don't assume character dimensions
70         buf.W = Term->TextWidth * giVT_CharWidth;
71         if( Count > 0 )
72         {
73                 buf.SrcY = (Term->ScrollTop+Count) * giVT_CharHeight;
74                 buf.DstY = Term->ScrollTop * giVT_CharHeight;
75         }
76         else    // Scroll up, move text down
77         {
78                 Count = -Count;
79                 buf.SrcY = Term->ScrollTop * giVT_CharHeight;
80                 buf.DstY = (Term->ScrollTop+Count) * giVT_CharHeight;
81         }
82         buf.H = (Term->ScrollHeight-Count) * giVT_CharHeight;
83         VFS_WriteAt(giVT_OutputDevHandle, 0, sizeof(buf), &buf);
84         
85         // Restore old mode (this function is only called during text mode)
86         tmp = VIDEO_BUFFMT_TEXT;
87         VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &tmp);
88         LEAVE('-');
89 }
90
91 void VT_int_UpdateCursor( tVTerm *Term, int bShow )
92 {
93         tVideo_IOCtl_Pos        csr_pos;
94
95         if( Term != gpVT_CurTerm )      return ;
96         
97         ENTER("pTerm bShow", Term, bShow);
98
99         if( !bShow )
100         {
101                 csr_pos.x = -1; 
102                 csr_pos.y = -1; 
103         }
104         else if( Term->Mode == TERM_MODE_TEXT )
105         {
106 //              if( !(Term->Flags & VT_FLAG_SHOWCSR)
107 //               && ( (Term->Flags & VT_FLAG_HIDECSR) || !Term->Node.ReadThreads)
108 //                )
109                 if( !Term->Text || Term->Flags & VT_FLAG_HIDECSR )
110                 {
111                         csr_pos.x = -1;
112                         csr_pos.y = -1;
113                 }
114                 else
115                 {
116                         const tVT_Pos   *wrpos = VT_int_GetWritePosPtr(Term);
117                         csr_pos.x = wrpos->Col;
118                         csr_pos.y = wrpos->Row - (Term->Flags & VT_FLAG_ALTBUF ? 0 : Term->ViewTopRow);
119                         if( 0 > csr_pos.y || csr_pos.y >= Term->TextHeight )
120                                 csr_pos.y = -1, csr_pos.x = -1;
121                 }
122         }
123         else
124         {
125                 csr_pos.x = Term->VideoCursorX;
126                 csr_pos.y = Term->VideoCursorY;
127         }
128         VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETCURSOR, &csr_pos);
129         LEAVE('-');
130 }       
131
132 /**
133  * \fn void VT_int_UpdateScreen( tVTerm *Term, int UpdateAll )
134  * \brief Updates the video framebuffer
135  */
136 void VT_int_UpdateScreen( tVTerm *Term, int UpdateAll )
137 {
138         ENTER("pTerm iUpdateAll", Term, UpdateAll);
139         // Only update if this is the current terminal
140         if( Term != gpVT_CurTerm ) {
141                 LOG("Term != gpVT_CurTerm (%p)", gpVT_CurTerm);
142                 LEAVE('-');
143                 return;
144         }
145                 
146         switch( Term->Mode )
147         {
148         case TERM_MODE_TEXT: {
149                 size_t view_pos = (Term->Flags & VT_FLAG_ALTBUF) ? 0 : Term->ViewTopRow*Term->TextWidth;
150                 const tVT_Pos *wrpos = VT_int_GetWritePosPtr(Term);
151                 const tVT_Char *buffer = (Term->Flags & VT_FLAG_ALTBUF) ? Term->AltBuf : Term->Text;
152                 LOG("view_pos = %i, wrpos = %p (R%i,C%i), buffer=%p", view_pos, wrpos, wrpos->Row, wrpos->Col, buffer);
153                 // Re copy the entire screen?
154                 if(UpdateAll) {
155                         VFS_WriteAt(
156                                 giVT_OutputDevHandle,
157                                 0,
158                                 Term->TextWidth*Term->TextHeight*sizeof(tVT_Char),
159                                 &buffer[view_pos]
160                                 );
161                 }
162                 // Only copy the current line
163                 else {
164                         size_t  ofs = wrpos->Row * Term->TextWidth;
165                         LOG("ofs = %i", ofs);
166                         VFS_WriteAt(
167                                 giVT_OutputDevHandle,
168                                 (ofs - view_pos)*sizeof(tVT_Char),
169                                 Term->TextWidth*sizeof(tVT_Char),
170                                 &buffer[ofs]
171                                 );
172                 }
173                 break; }
174         case TERM_MODE_FB:
175                 break;
176         }
177         
178         VT_int_UpdateCursor(Term, 1);
179         LEAVE('-');
180 }
181

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