4d1c352b3f1dbc535224aa9d8ff65018090b9aae
[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 #include "vterm.h"
9 #include <api_drv_video.h>
10 #define DEBUG   1
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         if( Count > Term->ScrollHeight )        Count = Term->ScrollHeight;
56         if( Count < -Term->ScrollHeight )       Count = -Term->ScrollHeight;
57         
58         // Switch to 2D Command Stream
59         tmp = VIDEO_BUFFMT_2DSTREAM;
60         VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &tmp);
61         
62         // BLIT to 0,0 from 0,giVT_CharHeight
63         buf.Op = VIDEO_2DOP_BLIT;
64         buf.SrcX = 0;   buf.DstX = 0;
65         // TODO: Don't assume character dimensions
66         buf.W = Term->TextWidth * giVT_CharWidth;
67         if( Count > 0 )
68         {
69                 buf.SrcY = (Term->ScrollTop+Count) * giVT_CharHeight;
70                 buf.DstY = Term->ScrollTop * giVT_CharHeight;
71         }
72         else    // Scroll up, move text down
73         {
74                 Count = -Count;
75                 buf.SrcY = Term->ScrollTop * giVT_CharHeight;
76                 buf.DstY = (Term->ScrollTop+Count) * giVT_CharHeight;
77         }
78         buf.H = (Term->ScrollHeight-Count) * giVT_CharHeight;
79         VFS_WriteAt(giVT_OutputDevHandle, 0, sizeof(buf), &buf);
80         
81         // Restore old mode (this function is only called during text mode)
82         tmp = VIDEO_BUFFMT_TEXT;
83         VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &tmp);
84 }
85
86 void VT_int_UpdateCursor( tVTerm *Term, int bShow )
87 {
88         tVideo_IOCtl_Pos        csr_pos;
89
90         if( Term != gpVT_CurTerm )      return ;
91
92         if( !bShow )
93         {
94                 csr_pos.x = -1; 
95                 csr_pos.y = -1; 
96         }
97         else if( Term->Mode == TERM_MODE_TEXT )
98         {
99                  int    offset;
100                 
101 //              if( !(Term->Flags & VT_FLAG_SHOWCSR)
102 //               && ( (Term->Flags & VT_FLAG_HIDECSR) || !Term->Node.ReadThreads)
103 //                )
104                 if( !Term->Text || Term->Flags & VT_FLAG_HIDECSR )
105                 {
106                         csr_pos.x = -1;
107                         csr_pos.y = -1;
108                 }
109                 else
110                 {
111                         if(Term->Flags & VT_FLAG_ALTBUF)
112                                 offset = Term->AltWritePos;
113                         else
114                                 offset = Term->WritePos - Term->ViewPos;
115                                         
116                         csr_pos.x = offset % Term->TextWidth;
117                         csr_pos.y = offset / Term->TextWidth;
118                         if( 0 > csr_pos.y || csr_pos.y >= Term->TextHeight )
119                                 csr_pos.y = -1, csr_pos.x = -1;
120                 }
121         }
122         else
123         {
124                 csr_pos.x = Term->VideoCursorX;
125                 csr_pos.y = Term->VideoCursorY;
126         }
127         VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETCURSOR, &csr_pos);
128 }       
129
130 /**
131  * \fn void VT_int_UpdateScreen( tVTerm *Term, int UpdateAll )
132  * \brief Updates the video framebuffer
133  */
134 void VT_int_UpdateScreen( tVTerm *Term, int UpdateAll )
135 {
136         tVT_Char        *buffer;
137          int    view_pos, write_pos;
138         // Only update if this is the current terminal
139         if( Term != gpVT_CurTerm )      return;
140         
141         switch( Term->Mode )
142         {
143         case TERM_MODE_TEXT:
144                 view_pos = (Term->Flags & VT_FLAG_ALTBUF) ? 0 : Term->ViewPos;
145                 write_pos = (Term->Flags & VT_FLAG_ALTBUF) ? Term->AltWritePos : Term->WritePos;
146                 buffer = (Term->Flags & VT_FLAG_ALTBUF) ? Term->AltBuf : Term->Text;
147                 // Re copy the entire screen?
148                 if(UpdateAll) {
149                         VFS_WriteAt(
150                                 giVT_OutputDevHandle,
151                                 0,
152                                 Term->TextWidth*Term->TextHeight*sizeof(tVT_Char),
153                                 &buffer[view_pos]
154                                 );
155                 }
156                 // Only copy the current line
157                 else {
158                          int    ofs = write_pos - write_pos % Term->TextWidth;
159                         VFS_WriteAt(
160                                 giVT_OutputDevHandle,
161                                 (ofs - view_pos)*sizeof(tVT_Char),
162                                 Term->TextWidth*sizeof(tVT_Char),
163                                 &buffer[ofs]
164                                 );
165                 }
166                 break;
167         case TERM_MODE_FB:
168                 break;
169         }
170         
171         VT_int_UpdateCursor(Term, 1);
172 }
173

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