FreeNOS
Terminal.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2009 Niek Linnenbank
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <Types.h>
19#include <Macros.h>
20#include <VGA.h>
21#include <Runtime.h>
22#include "Terminal.h"
23#include <stdio.h>
24#include <stdlib.h>
25#include <fcntl.h>
26#include <unistd.h>
27#include <string.h>
28
41
43 const char *in,
44 const char *out,
45 const Size w,
46 const Size h)
47 : Device(inode, FileSystem::CharacterDeviceFile)
48 , inputFile(in)
49 , outputFile(out)
50 , width(w)
51 , height(h)
52{
53 m_identifier << "tty0";
54 buffer = new u16[width * height];
55}
56
58{
59 teken_pos_t winsz;
60
61 // Close standard I/O
62 ::close(0);
63 ::close(1);
64
65 // Attempt to open input file.
66 if ((input = ::open(inputFile, O_RDONLY)) < 0)
67 {
68 printf("failed to open `%s': %s\r\n",
71 }
72
73 // Then open the output file.
74 if ((output = ::open(outputFile, O_RDWR)) < 0)
75 {
76 printf("failed to open `%s': %s\r\n",
79 }
80
81 // Fill in function pointers
89
90 // Reset cursor
91 memset(&cursorPos, 0, sizeof(cursorPos));
92
93 // Initialize libteken
94 teken_init(&state, &funcs, this);
95
96 // Set appropriate terminal sizes
97 winsz.tp_col = 80;
98 winsz.tp_row = 25;
99 teken_set_winsize(&state, &winsz);
100
101 // Print banners
102 writeTerminal((const u8 *)(BANNER COPYRIGHT "\r\n"), strlen(BANNER)+strlen(COPYRIGHT)+2);
103
104 // Done
105 return FileSystem::Success;
106}
107
109{
110 delete buffer;
111 ::close(input);
113}
114
116{
117 return width;
118}
119
121{
122 return height;
123}
124
126{
127 return input;
128}
129
131{
132 return output;
133}
134
136{
137 return buffer;
138}
139
141{
142 return &cursorValue;
143}
144
146 Size & size,
147 const Size offset)
148{
149 char tmp[255];
150 int n;
151
152 n = ::read(input, tmp, size < sizeof(tmp) ? size : sizeof(tmp));
153 if (n < 0)
154 {
155 return FileSystem::IOError;
156 }
157 else if (n > 0)
158 {
159 buffer.write(tmp, n);
160 }
161
162 size = n;
163 return FileSystem::Success;
164}
165
167 Size & size,
168 const Size offset)
169{
170 return writeTerminal(buffer.getBuffer(), size);
171}
172
174 const Size size)
175{
176 char cr = '\r', ch;
177
178 // Initialize buffer with the current screen first
180 ::read(output, this->buffer, width * height * 2);
181
182 // Loop all input characters. Add an additional carriage return
183 // whenever a linefeed is detected.
184 for (Size i = 0; i < size; i++)
185 {
186 if (bytes[i] == '\n')
187 {
188 teken_input(&state, &cr, 1);
189 }
190 ch = bytes[i];
191 teken_input(&state, &ch, 1);
192 }
193
194 // Flush changes back to our output device
196 ::write(output, this->buffer, width * height * 2);
197
198 // Done
199 return FileSystem::Success;
200}
201
203{
205
206 // Restore old attributes
207 buffer[index] &= 0xff;
208 buffer[index] |= (cursorValue & 0xff00);
209}
210
212{
213 // Save value
214 cursorValue = buffer[pos->tp_col + (pos->tp_row * width)];
215 cursorPos = *pos;
216}
217
219{
221
222 // Refresh cursorValue first
224
225 // Write cursor
226 buffer[index] &= 0xff;
227 buffer[index] |= VGA_ATTR(LIGHTGREY, LIGHTGREY) << 8;
228}
229
230void bell(Terminal *term)
231{
232 // Does nothing yet
233}
234
235void putchar(Terminal *term, const teken_pos_t *pos,
236 teken_char_t ch, const teken_attr_t *attr)
237{
238 // Retrieve variables first
239 u16 *buffer = term->getBuffer();
240 Size width = term->getWidth();
241
242 // Make sure to don't overwrite cursor
243 term->hideCursor();
244
245 // Write the buffer
246 buffer[pos->tp_col + (pos->tp_row * width)] =
247 VGA_CHAR(ch, tekenToVGA[attr->ta_fgcolor], BLACK);
248
249 // Show cursor again
250 term->showCursor();
251}
252
253void cursor(Terminal *term, const teken_pos_t *pos)
254{
255 term->hideCursor();
256 term->setCursor(pos);
257 term->showCursor();
258}
259
260void fill(Terminal *term, const teken_rect_t *rect,
261 teken_char_t ch, const teken_attr_t *attr)
262{
263 // Make sure we don't overwrite the cursor
264 term->hideCursor();
265
266 // Fill video memory; loop rows
267 for (Size row = rect->tr_begin.tp_row;
268 row < rect->tr_end.tp_row; row++)
269 {
270 // Loop columns
271 for (Size col = rect->tr_begin.tp_col;
272 col < rect->tr_end.tp_col; col++)
273 {
274 term->getBuffer()[col + (row * term->getWidth())] =
275 VGA_CHAR(ch, tekenToVGA[attr->ta_fgcolor], BLACK);
276 }
277 }
278 // Show cursor again
279 term->showCursor();
280}
281
282void copy(Terminal *term, const teken_rect_t *rect,
283 const teken_pos_t *pos)
284{
285 // Retrieve variables
286 u16 *buffer = term->getBuffer();
287 Size width = term->getWidth();
288
289 // Calculate sizes
290 Size numCols = rect->tr_end.tp_col - rect->tr_begin.tp_col;
291 Size numRows = rect->tr_end.tp_row - rect->tr_begin.tp_row;
292
293 // Hide cursor first
294 term->hideCursor();
295
296 // Copy video memory
297 memcpy(buffer + pos->tp_col + (pos->tp_row * width),
298 buffer + rect->tr_begin.tp_col + (rect->tr_begin.tp_row * width),
299 numCols + (numRows * width) * sizeof(u16));
300
301 // Show cursor again
302 term->showCursor();
303}
304
305void param(Terminal *term, int key, int value)
306{
307 // Do nothing
308}
309
310void respond(Terminal *ctx, const void *buf, size_t size)
311{
312 // Do nothing
313}
u8 tekenToVGA[]
Definition Terminal.cpp:29
Abstract device class interface.
Definition Device.h:36
String m_identifier
Unique identifier for this Device.
Definition Device.h:79
Abstract Input/Output buffer.
Definition IOBuffer.h:38
A Terminal enables user to interact with the system.
Definition Terminal.h:45
void setCursor(const teken_pos_t *pos)
Sets the new position of the cursor.
Definition Terminal.cpp:211
const Size height
Definition Terminal.h:201
virtual FileSystem::Result write(IOBuffer &buffer, Size &size, const Size offset)
Write bytes to the Terminal.
Definition Terminal.cpp:166
teken_t state
Terminal state.
Definition Terminal.h:179
FileSystem::Result writeTerminal(const u8 *bytes, const Size size)
Write bytes to the output device.
Definition Terminal.cpp:173
void hideCursor()
Hides the cursor from the VGA screen.
Definition Terminal.cpp:202
const char * outputFile
Definition Terminal.h:196
teken_pos_t cursorPos
Saved cursor position.
Definition Terminal.h:188
u16 * buffer
Buffer for local Terminal updates.
Definition Terminal.h:185
u16 * getCursorValue()
Saved byte and attribute value at cursor position.
Definition Terminal.cpp:140
virtual FileSystem::Result read(IOBuffer &buffer, Size &size, const Size offset)
Read bytes from the Terminal.
Definition Terminal.cpp:145
const char * inputFile
Path to the input and output files.
Definition Terminal.h:196
virtual FileSystem::Result initialize()
Initialize the Terminal.
Definition Terminal.cpp:57
teken_funcs_t funcs
Terminal function handlers.
Definition Terminal.h:182
int input
Input and output file descriptors.
Definition Terminal.h:204
int getInput()
Retrieve file descriptor of the input source.
Definition Terminal.cpp:125
const Size width
Width and height of the Terminal.
Definition Terminal.h:201
Size getWidth()
Retrieve the width of the Terminal.
Definition Terminal.cpp:115
u16 cursorValue
Saved value at cursor position.
Definition Terminal.h:191
int output
Definition Terminal.h:204
Size getHeight()
Retrieve the height of the Terminal.
Definition Terminal.cpp:120
void showCursor()
Show the VGA cursor.
Definition Terminal.cpp:218
u16 * getBuffer()
Retrieve a pointer to the local buffer.
Definition Terminal.cpp:135
virtual ~Terminal()
Class destructor.
Definition Terminal.cpp:108
int getOutput()
Retrieve file descriptor of the output source.
Definition Terminal.cpp:130
Terminal(const u32 inode, const char *inputFile, const char *outputFile, const Size width=80, const Size height=25)
Class constructor.
Definition Terminal.cpp:42
#define SEEK_SET
Seek relative to start-of-file.
Definition stdio.h:46
C size_t strlen(const char *str)
Calculate the length of a string.
Definition strlen.cpp:21
C int open(const char *path, int oflag,...)
Open file relative to directory file descriptor.
Definition open.cpp:26
C char * strerror(int errnum)
The strerror function maps the number in errnum to a message string.
Definition strerror.cpp:20
C int close(int fildes)
Close a file descriptor.
Definition close.cpp:22
C int errno
The lvalue errno is used by many functions to return error values.
C void * memset(void *dest, int ch, size_t count)
Fill memory with a constant byte.
Definition memset.cpp:20
C off_t lseek(int fildes, off_t offset, int whence)
Move the read/write file offset.
Definition lseek.cpp:22
C void * memcpy(void *dest, const void *src, size_t count)
Copy memory from one place to another.
Definition memcpy.cpp:20
#define O_RDONLY
Open for reading only.
Definition fcntl.h:81
C int printf(const char *format,...)
Output a formatted string to standard output.
Definition printf.cpp:22
#define O_RDWR
Open for reading and writing.
Definition fcntl.h:84
unsigned int u32
Unsigned 32-bit number.
Definition Types.h:53
unsigned short u16
Unsigned 16-bit number.
Definition Types.h:56
unsigned int Size
Any sane size indicator cannot go negative.
Definition Types.h:128
unsigned char u8
Unsigned 8-bit number.
Definition Types.h:59
void respond(Terminal *ctx, const void *buf, size_t size)
Unused.
Definition Terminal.cpp:310
void param(Terminal *ctx, int key, int value)
Set terminal parameters.
Definition Terminal.cpp:305
#define BANNER
Print this banner per default on new Terminals.
Definition Terminal.h:38
#define BLACK
void bell(Terminal *term)
Makes a sound (bell).
Definition Terminal.cpp:230
#define RED
void cursor(Terminal *term, const teken_pos_t *pos)
Sets the Terminal cursor.
Definition Terminal.cpp:253
void copy(Terminal *ctx, const teken_rect_t *rect, const teken_pos_t *pos)
Copy bytes to the terminal.
Definition Terminal.cpp:282
void putchar(Terminal *term, const teken_pos_t *pos, teken_char_t ch, const teken_attr_t *attr)
Output a new character.
Definition Terminal.cpp:235
void fill(Terminal *ctx, const teken_rect_t *rect, teken_char_t ch, const teken_attr_t *attr)
Fills the Terminal buffer with a character.
Definition Terminal.cpp:260
#define VGA_ATTR(front, back)
Encodes VGA attributes.
Definition VGA.h:48
#define VGA_CHAR(ch, front, back)
Encodes a character for VGA output.
Definition VGA.h:58
@ LIGHTGREY
Definition VGA.h:73
@ LIGHTGREEN
Definition VGA.h:76
@ LIGHTBLUE
Definition VGA.h:75
@ LIGHTBROWN
Definition VGA.h:80
@ LIGHTCYAN
Definition VGA.h:77
@ LIGHTMAGENTA
Definition VGA.h:79
Result
Result code for filesystem Actions.
Definition FileSystem.h:53
teken_color_t ta_fgcolor
Definition teken.h:78
tf_cursor_t * tf_cursor
Definition teken.h:115
tf_param_t * tf_param
Definition teken.h:119
tf_copy_t * tf_copy
Definition teken.h:118
tf_putchar_t * tf_putchar
Definition teken.h:116
tf_bell_t * tf_bell
Definition teken.h:114
tf_fill_t * tf_fill
Definition teken.h:117
tf_respond_t * tf_respond
Definition teken.h:120
teken_unit_t tp_col
Definition teken.h:70
teken_unit_t tp_row
Definition teken.h:69
teken_pos_t tr_begin
Definition teken.h:73
teken_pos_t tr_end
Definition teken.h:74
void teken_init(teken_t *t, const teken_funcs_t *tf, void *softc)
Definition teken.c:173
void teken_input(teken_t *t, const void *buf, size_t len)
Definition teken.c:289
void teken_set_winsize(teken_t *t, const teken_pos_t *p)
Definition teken.c:337
void tf_bell_t(void *)
Definition teken.h:94
void tf_param_t(void *, int, unsigned int)
Definition teken.h:101
void tf_respond_t(void *, const void *, size_t)
Definition teken.h:111
void tf_fill_t(void *, const teken_rect_t *, teken_char_t, const teken_attr_t *)
Definition teken.h:98
unsigned char teken_char_t
Definition teken.h:49
void tf_cursor_t(void *, const teken_pos_t *)
Definition teken.h:95
void tf_copy_t(void *, const teken_rect_t *, const teken_pos_t *)
Definition teken.h:100
void tf_putchar_t(void *, const teken_pos_t *, teken_char_t, const teken_attr_t *)
Definition teken.h:96