Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#pragma once
28
29#include <Kernel/Devices/KeyboardDevice.h>
30#include <Kernel/TTY/TTY.h>
31#include <LibBareMetal/Output/Console.h>
32
33namespace Kernel {
34
35class VirtualConsole final : public TTY
36 , public KeyboardClient
37 , public ConsoleImplementation {
38 AK_MAKE_ETERNAL
39public:
40 enum InitialContents {
41 Cleared,
42 AdoptCurrentVGABuffer
43 };
44
45 VirtualConsole(unsigned index, InitialContents = Cleared);
46 virtual ~VirtualConsole() override;
47
48 static void switch_to(unsigned);
49 static void initialize();
50
51 bool is_graphical() { return m_graphical; }
52 void set_graphical(bool graphical);
53
54private:
55 // ^KeyboardClient
56 virtual void on_key_pressed(KeyboardDevice::Event) override;
57
58 // ^ConsoleImplementation
59 virtual void on_sysconsole_receive(u8) override;
60
61 // ^TTY
62 virtual ssize_t on_tty_write(const u8*, ssize_t) override;
63 virtual StringView tty_name() const override;
64 virtual void echo(u8) override;
65
66 // ^CharacterDevice
67 virtual const char* class_name() const override { return "VirtualConsole"; }
68
69 void set_active(bool);
70 void on_char(u8);
71
72 void get_vga_cursor(u8& row, u8& column);
73 void flush_vga_cursor();
74
75 u8* m_buffer;
76 unsigned m_index;
77 bool m_active { false };
78 bool m_graphical { false };
79
80 void scroll_up();
81 void set_cursor(unsigned row, unsigned column);
82 void put_character_at(unsigned row, unsigned column, u8 ch);
83
84 void escape$A(const Vector<unsigned>&);
85 void escape$D(const Vector<unsigned>&);
86 void escape$H(const Vector<unsigned>&);
87 void escape$J(const Vector<unsigned>&);
88 void escape$m(const Vector<unsigned>&);
89 void escape$s(const Vector<unsigned>&);
90 void escape$u(const Vector<unsigned>&);
91
92 void clear();
93
94 u8 m_cursor_row { 0 };
95 u8 m_cursor_column { 0 };
96 u8 m_saved_cursor_row { 0 };
97 u8 m_saved_cursor_column { 0 };
98 u8 m_current_attribute { 0x07 };
99
100 void clear_vga_row(u16 row);
101 void set_vga_start_row(u16 row);
102 u16 m_vga_start_row { 0 };
103 u16 m_current_vga_start_address { 0 };
104 u8* m_current_vga_window { nullptr };
105
106 void execute_escape_sequence(u8 final);
107
108 enum EscapeState {
109 Normal,
110 ExpectBracket,
111 ExpectParameter,
112 ExpectIntermediate,
113 ExpectFinal,
114 };
115 EscapeState m_escape_state { Normal };
116 Vector<u8> m_parameters;
117 Vector<u8> m_intermediates;
118 u8* m_horizontal_tabs { nullptr };
119 char m_tty_name[32];
120};
121
122}