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

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