/* * Copyright (c) 2018-2021, Andreas Kling * Copyright (c) 2021, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Kernel { class ConsoleManagement; class VirtualConsole; // FIXME: This implementation has no knowledge about keeping terminal history... class ConsoleImpl final : public VT::Terminal { public: explicit ConsoleImpl(VirtualConsole&); virtual void set_size(u16 columns, u16 rows) override; private: virtual void invalidate_cursor() override; virtual void clear() override; virtual void clear_history() override; virtual void scroll_up(u16 region_top, u16 region_bottom, size_t count) override; virtual void scroll_down(u16 region_top, u16 region_bottom, size_t count) override; virtual void scroll_left(u16 row, u16 column, size_t count) override; virtual void scroll_right(u16 row, u16 column, size_t count) override; virtual void put_character_at(unsigned row, unsigned column, u32 ch) override; virtual void clear_in_line(u16 row, u16 first_column, u16 last_column) override; }; class VirtualConsole final : public TTY , public KeyboardClient , public VT::TerminalClient { AK_MAKE_ETERNAL friend class ConsoleManagement; friend class DeviceManagement; friend class ConsoleImpl; friend class VT::Terminal; public: struct Line { bool dirty; size_t length; }; struct Cell { void clear() { ch = ' '; attribute.reset(); } char ch; VT::Attribute attribute; }; public: static NonnullRefPtr create(size_t index); static NonnullRefPtr create_with_preset_log(size_t index, const CircularQueue&); virtual ~VirtualConsole() override; size_t index() const { return m_index; } void refresh_after_resolution_change(); bool is_graphical() { return m_graphical; } void set_graphical(bool graphical); void emit_char(char); private: explicit VirtualConsole(const unsigned index); VirtualConsole(const unsigned index, const CircularQueue&); // ^KeyboardClient virtual void on_key_pressed(KeyEvent) override; // ^TTY virtual KResultOr on_tty_write(const UserOrKernelBuffer&, size_t) override; virtual String const& tty_name() const override { return m_tty_name; } virtual void echo(u8) override; // ^TerminalClient virtual void beep() override; virtual void set_window_title(const StringView&) override; virtual void set_window_progress(int, int) override; virtual void terminal_did_resize(u16 columns, u16 rows) override; virtual void terminal_history_changed(int) override; virtual void emit(const u8*, size_t) override; virtual void set_cursor_style(VT::CursorStyle) override; // ^CharacterDevice virtual StringView class_name() const override { return "VirtualConsole"sv; } void set_active(bool); void flush_dirty_lines(); unsigned m_index; bool m_active { false }; bool m_graphical { false }; String m_tty_name; private: void initialize(); void invalidate_cursor(size_t row); void clear(); void inject_string(const StringView&); Cell& cell_at(size_t column, size_t row); using ParamVector = Vector; void on_code_point(u32); void scroll_down(u16 region_top, u16 region_bottom, size_t count); void scroll_up(u16 region_top, u16 region_bottom, size_t count); void scroll_left(u16 row, u16 column, size_t count); void scroll_right(u16 row, u16 column, size_t count); void clear_line(size_t index) { clear_in_line(index, 0, m_console_impl.columns() - 1); } void clear_in_line(u16 row, u16 first_column, u16 last_column); void put_character_at(unsigned row, unsigned column, u32 ch, const VT::Attribute&); OwnPtr m_cells; Vector m_lines; ConsoleImpl m_console_impl; }; }