1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#pragma once
4
5#include <ansi_colors.h>
6#include <mos/io/io.hpp>
7#include <mos/lib/structures/list.hpp>
8#include <mos/lib/structures/ring_buffer.hpp>
9#include <mos/lib/sync/spinlock.hpp>
10#include <mos/mos_global.h>
11#include <mos/tasks/wait.hpp>
12#include <mos/types.hpp>
13
14typedef enum
15{
16 CONSOLE_CAP_COLOR = 1 << 0,
17 CONSOLE_CAP_CLEAR = 1 << 1,
18 CONSOLE_CAP_GET_SIZE = 1 << 2,
19 CONSOLE_CAP_CURSOR_HIDE = 1 << 3,
20 CONSOLE_CAP_CURSOR_MOVE = 1 << 4,
21 CONSOLE_CAP_READ = 1 << 6, ///< console supports read
22} console_caps;
23
24MOS_ENUM_OPERATORS(console_caps)
25
26template<size_t buf_size>
27struct Buffer
28{
29 u8 buf[buf_size] __aligned(buf_size) = { 0 };
30 const size_t size = buf_size;
31};
32
33struct Console // : public io_t
34{
35 as_linked_list;
36 io_t io;
37 const char *name = "<unnamed>";
38 console_caps caps;
39 waitlist_t waitlist; // waitlist for read
40
41 template<size_t buf_size>
42 Console(const char *name, console_caps caps, Buffer<buf_size> *read_buf, standard_color_t default_fg, standard_color_t default_bg)
43 : name(name), caps(caps), fg(default_fg), bg(default_bg), default_fg(default_fg), default_bg(default_bg)
44 {
45 reader.buf = read_buf->buf;
46 reader.size = read_buf->size;
47 waitlist_init(list: &waitlist);
48 }
49
50 virtual ~Console() = default;
51
52 struct
53 {
54 spinlock_t lock;
55 ring_buffer_pos_t pos;
56 u8 *buf = nullptr;
57 size_t size = 0;
58 } reader;
59
60 struct
61 {
62 spinlock_t lock;
63 } writer;
64
65 standard_color_t fg, bg;
66 standard_color_t default_fg = White, default_bg = Black;
67
68 public:
69 size_t write(const char *data, size_t size)
70 {
71 spinlock_acquire(&writer.lock);
72 size_t ret = do_write(data, size);
73 spinlock_release(&writer.lock);
74 return ret;
75 }
76
77 size_t write_color(const char *data, size_t size, standard_color_t fg, standard_color_t bg)
78 {
79 spinlock_acquire(&writer.lock);
80 if (caps & CONSOLE_CAP_COLOR)
81 {
82 if (this->fg != fg || this->bg != bg)
83 {
84 set_color(fg, bg);
85 this->fg = fg;
86 this->bg = bg;
87 }
88 }
89
90 size_t ret = do_write(data, size);
91 spinlock_release(&writer.lock);
92 return ret;
93 }
94
95 void putc(u8 c);
96
97 public:
98 virtual bool extra_setup()
99 {
100 return true;
101 }
102
103 virtual bool get_size(u32 *width, u32 *height) = 0;
104 virtual bool set_color(standard_color_t fg, standard_color_t bg) = 0;
105 virtual bool clear() = 0;
106
107 public: // TODO: make protected
108 virtual size_t do_write(const char *data, size_t size) = 0;
109};
110
111extern list_head consoles;
112
113void console_register(Console *con);
114Console *console_get(const char *name);
115Console *console_get_by_prefix(const char *prefix);
116