forked from Bananymous/banan-os
				
			
		
			
				
	
	
		
			107 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			107 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C++
		
	
	
	
| #pragma once
 | |
| 
 | |
| #include <LibFont/Font.h>
 | |
| 
 | |
| #include <LibGUI/Window.h>
 | |
| 
 | |
| struct Rectangle
 | |
| {
 | |
| 	uint32_t x      { 0 };
 | |
| 	uint32_t y      { 0 };
 | |
| 	uint32_t width  { 0 };
 | |
| 	uint32_t height { 0 };
 | |
| 
 | |
| 	Rectangle get_bounding_box(Rectangle other) const
 | |
| 	{
 | |
| 		const auto min_x = BAN::Math::min(x, other.x);
 | |
| 		const auto min_y = BAN::Math::min(y, other.y);
 | |
| 		const auto max_x = BAN::Math::max(x + width, other.x + other.width);
 | |
| 		const auto max_y = BAN::Math::max(y + height, other.y + other.height);
 | |
| 		return Rectangle {
 | |
| 			.x = min_x,
 | |
| 			.y = min_y,
 | |
| 			.width = max_x - min_x,
 | |
| 			.height = max_y - min_y,
 | |
| 		};
 | |
| 	}
 | |
| };
 | |
| 
 | |
| class Terminal
 | |
| {
 | |
| public:
 | |
| 	void run();
 | |
| 
 | |
| 	uint32_t cols() const { return m_window->width() / m_font.width(); }
 | |
| 	uint32_t rows() const { return m_window->height() / m_font.height(); }
 | |
| 
 | |
| private:
 | |
| 	void handle_sgr(int32_t value);
 | |
| 	Rectangle handle_csi(char ch);
 | |
| 	Rectangle putcodepoint(uint32_t codepoint);
 | |
| 	Rectangle putchar(uint8_t ch);
 | |
| 	bool read_shell();
 | |
| 
 | |
| 	BAN::Optional<uint32_t> get_8bit_color();
 | |
| 	BAN::Optional<uint32_t> get_24bit_color();
 | |
| 
 | |
| 	void hide_cursor();
 | |
| 	void show_cursor();
 | |
| 
 | |
| 	void on_key_event(LibGUI::EventPacket::KeyEvent::event_t);
 | |
| 
 | |
| 	void start_shell();
 | |
| 
 | |
| private:
 | |
| 	struct Cursor
 | |
| 	{
 | |
| 		uint32_t x;
 | |
| 		uint32_t y;
 | |
| 	};
 | |
| 
 | |
| 	struct ShellInfo
 | |
| 	{
 | |
| 		int pts_master;
 | |
| 		pid_t pid;
 | |
| 	};
 | |
| 
 | |
| 	enum class State
 | |
| 	{
 | |
| 		Normal,
 | |
| 		ESC,
 | |
| 		CSI,
 | |
| 	};
 | |
| 
 | |
| 	struct CSIInfo
 | |
| 	{
 | |
| 		static constexpr size_t max_fields = 5;
 | |
| 		int32_t fields[max_fields];
 | |
| 		size_t index;
 | |
| 		bool question;
 | |
| 	};
 | |
| 
 | |
| private:
 | |
| 	BAN::UniqPtr<LibGUI::Window> m_window;
 | |
| 	LibFont::Font m_font;
 | |
| 	ShellInfo m_shell_info;
 | |
| 	State m_state { State::Normal };
 | |
| 	CSIInfo m_csi_info;
 | |
| 
 | |
| 	bool m_cursor_shown { true };
 | |
| 	bool m_cursor_blink_shown { true };
 | |
| 	uint64_t m_cursor_blink_ms { 0 };
 | |
| 	Cursor m_cursor { 0, 0 };
 | |
| 	BAN::Vector<uint32_t> m_cursor_buffer;
 | |
| 	bool m_got_key_event { false };
 | |
| 
 | |
| 	uint8_t m_utf8_index { 0 };
 | |
| 	uint8_t m_utf8_bytes[4] { };
 | |
| 
 | |
| 	uint32_t m_last_graphic_char { 0 };
 | |
| 
 | |
| 	Cursor m_saved_cursor { 0, 0 };
 | |
| 	uint32_t m_fg_color { 0 };
 | |
| 	uint32_t m_bg_color { 0 };
 | |
| 	bool m_colors_inverted { false };
 | |
| 	bool m_is_bold { false };
 | |
| };
 |