mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-17 08:37:17 -04:00
Cleanup the terminal system
This commit is contained in:
parent
565c364f6f
commit
321c6dcf5d
@ -16,30 +16,68 @@
|
||||
|
||||
namespace stdio {
|
||||
|
||||
/*!
|
||||
* \brief Init the console
|
||||
*/
|
||||
void init_console();
|
||||
|
||||
/*!
|
||||
* \brief A console
|
||||
*/
|
||||
struct console {
|
||||
/*!
|
||||
* \brief Init the console
|
||||
*/
|
||||
void init();
|
||||
|
||||
size_t get_columns() const ;
|
||||
size_t get_rows() const ;
|
||||
/*!
|
||||
* \brief Returns the number of columns of the console
|
||||
*/
|
||||
size_t get_columns() const;
|
||||
|
||||
/*!
|
||||
* \brief Returns the number of rows of the console
|
||||
*/
|
||||
size_t get_rows() const;
|
||||
|
||||
/*!
|
||||
* \brief Print the given char to the console
|
||||
* \param c The character to print
|
||||
*/
|
||||
void print(char c);
|
||||
|
||||
/*!
|
||||
* \brief Clear the console
|
||||
*/
|
||||
void wipeout();
|
||||
|
||||
/*!
|
||||
* \brief Set the active status of the console
|
||||
* \param active The active status of the console
|
||||
*/
|
||||
void set_active(bool active);
|
||||
|
||||
/*!
|
||||
* \brief Save the state of the console
|
||||
*/
|
||||
void save();
|
||||
|
||||
/*!
|
||||
* \brief Restore the state of the console
|
||||
*/
|
||||
void restore();
|
||||
|
||||
private:
|
||||
/*!
|
||||
* \brief Move to the next line
|
||||
*/
|
||||
void next_line();
|
||||
|
||||
size_t current_line = 0;
|
||||
size_t current_column = 0;
|
||||
size_t current_line = 0; ///< The current line of the console
|
||||
size_t current_column = 0; ///< The current column of the console
|
||||
|
||||
void* buffer = nullptr;
|
||||
bool active = false;
|
||||
void* buffer = nullptr; ///< The buffer to save the state
|
||||
bool active = false; ///< The active status of the console
|
||||
};
|
||||
|
||||
} // end of namespace stdio
|
||||
|
@ -14,14 +14,40 @@
|
||||
|
||||
namespace stdio {
|
||||
|
||||
/*!
|
||||
* \brief Initialize the terminals
|
||||
*/
|
||||
void init_terminals();
|
||||
|
||||
/*!
|
||||
* \brief Register the devices into the devfs
|
||||
*/
|
||||
void register_devices();
|
||||
|
||||
/*!
|
||||
* \brief Finalize the terminals
|
||||
*/
|
||||
void finalize();
|
||||
|
||||
/*!
|
||||
* \brief Switch the active terminal to the terminal with the given id
|
||||
* \param id The terminal to activate
|
||||
*/
|
||||
void switch_terminal(size_t id);
|
||||
|
||||
/*!
|
||||
* \brief Returns the number of terminals
|
||||
*/
|
||||
size_t terminals_count();
|
||||
|
||||
/*!
|
||||
* \brief Returns the active terminal
|
||||
*/
|
||||
virtual_terminal& get_active_terminal();
|
||||
|
||||
/*!
|
||||
* \brief Returns the terminal with the given id
|
||||
*/
|
||||
virtual_terminal& get_terminal(size_t id);
|
||||
|
||||
} //end of namespace stdio
|
||||
|
@ -23,7 +23,13 @@ namespace stdio {
|
||||
|
||||
constexpr const size_t INPUT_BUFFER_SIZE = 256;
|
||||
|
||||
/*!
|
||||
* \brief A virtual terminal
|
||||
*/
|
||||
struct virtual_terminal {
|
||||
/*!
|
||||
* \brief Construct a new virtual_terminal
|
||||
*/
|
||||
virtual_terminal(){}
|
||||
|
||||
virtual_terminal(const virtual_terminal& rhs) = delete;
|
||||
@ -32,6 +38,10 @@ struct virtual_terminal {
|
||||
virtual_terminal(virtual_terminal&& rhs) = delete;
|
||||
virtual_terminal& operator=(virtual_terminal&& rhs) = delete;
|
||||
|
||||
/*!
|
||||
* \brief Print the given char to the terminal
|
||||
* \param c The character to print
|
||||
*/
|
||||
void print(char c);
|
||||
|
||||
/*!
|
||||
@ -76,13 +86,36 @@ struct virtual_terminal {
|
||||
*/
|
||||
size_t read_input_raw(size_t ms);
|
||||
|
||||
/*!
|
||||
* \brief Set the canonical mode of the terminal
|
||||
* \param can The canonical mode of the terminal
|
||||
*/
|
||||
void set_canonical(bool can);
|
||||
|
||||
/*!
|
||||
* \brief Set the mouse mode of the terminal
|
||||
* \param can The mouse mode of the terminal
|
||||
*/
|
||||
void set_mouse(bool m);
|
||||
|
||||
/*!
|
||||
* \brief Returns true if the terminal is in canonical mode, false otherwise
|
||||
*/
|
||||
bool is_canonical() const;
|
||||
|
||||
/*!
|
||||
* \brief Returns true if the terminal is in mouse mode, false otherwise
|
||||
*/
|
||||
bool is_mouse() const;
|
||||
|
||||
/*!
|
||||
* \brief Set the active mode of the terminal
|
||||
*/
|
||||
void set_active(bool);
|
||||
|
||||
/*!
|
||||
* \brief Returns the console linked to this terminal
|
||||
*/
|
||||
console& get_console();
|
||||
|
||||
size_t id;
|
||||
|
@ -10,12 +10,41 @@
|
||||
|
||||
#include <types.hpp>
|
||||
|
||||
/*!
|
||||
* \brief A textual console
|
||||
*/
|
||||
struct text_console {
|
||||
/*!
|
||||
* \brief Initialize the console
|
||||
*/
|
||||
void init();
|
||||
|
||||
/*!
|
||||
* \brief Returns the number of lines of the console
|
||||
*/
|
||||
size_t lines();
|
||||
|
||||
/*!
|
||||
* \brief Returns the number of columns of the console
|
||||
*/
|
||||
size_t columns();
|
||||
|
||||
/*!
|
||||
* \brief Clear the text console
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/*!
|
||||
* \brief Scroll up one line
|
||||
*/
|
||||
void scroll_up();
|
||||
|
||||
/*!
|
||||
* \brief Print a char at the given line and column
|
||||
* \param line The line at which to print the char
|
||||
* \param column The column at which to print the char
|
||||
* \param c The char to print
|
||||
*/
|
||||
void print_char(size_t line, size_t column, char c);
|
||||
};
|
||||
|
||||
|
@ -10,22 +10,75 @@
|
||||
|
||||
#include <types.hpp>
|
||||
|
||||
/*!
|
||||
* \brief A VESA console
|
||||
*/
|
||||
struct vesa_console {
|
||||
/*!
|
||||
* \brief Initialize the console
|
||||
*/
|
||||
void init();
|
||||
|
||||
size_t lines() const ;
|
||||
size_t columns() const ;
|
||||
/*!
|
||||
* \brief Returns the number of lines of the console
|
||||
*/
|
||||
size_t lines() const;
|
||||
|
||||
/*!
|
||||
* \brief Returns the number of columns of the console
|
||||
*/
|
||||
size_t columns() const;
|
||||
|
||||
/*!
|
||||
* \brief Clear the vesa console
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/*!
|
||||
* \brief Clear the given vesa console state
|
||||
* \param buffer The VESA console state
|
||||
*/
|
||||
void clear(void* buffer);
|
||||
|
||||
/*!
|
||||
* \brief Scroll up one line
|
||||
*/
|
||||
void scroll_up();
|
||||
|
||||
/*!
|
||||
* \brief Scroll up one line on the given vesa console state
|
||||
* \param buffer The VESA console state
|
||||
*/
|
||||
void scroll_up(void* buffer);
|
||||
|
||||
/*!
|
||||
* \brief Print a char at the given line and column
|
||||
* \param line The line at which to print the char
|
||||
* \param column The column at which to print the char
|
||||
* \param c The char to print
|
||||
*/
|
||||
void print_char(size_t line, size_t column, char c);
|
||||
|
||||
/*!
|
||||
* \brief Print a char at the given line and column on the given vesa console state
|
||||
* \param buffer The VESA console state
|
||||
* \param line The line at which to print the char
|
||||
* \param column The column at which to print the char
|
||||
* \param c The char to print
|
||||
*/
|
||||
void print_char(void* buffer, size_t line, size_t column, char c);
|
||||
|
||||
/*!
|
||||
* \brief Save the state of the console
|
||||
* \param buffer The buffer to save to
|
||||
* \return the buffer the state was saved to
|
||||
*/
|
||||
void* save(void* buffer);
|
||||
|
||||
/*!
|
||||
* \brief Restore the state of the console
|
||||
* \param buffer The buffer to restore from
|
||||
*/
|
||||
void restore(void* buffer);
|
||||
};
|
||||
|
||||
|
@ -26,24 +26,24 @@ bool text = true;
|
||||
|
||||
} //end of anonymous namespace
|
||||
|
||||
void stdio::init_console(){
|
||||
void stdio::init_console() {
|
||||
text = !vesa::enabled();
|
||||
|
||||
if(text){
|
||||
if (text) {
|
||||
t_console.init();
|
||||
} else {
|
||||
v_console.init();
|
||||
}
|
||||
}
|
||||
|
||||
void stdio::console::init(){
|
||||
if(!text){
|
||||
void stdio::console::init() {
|
||||
if (!text) {
|
||||
buffer = vesa::create_buffer();
|
||||
}
|
||||
}
|
||||
|
||||
size_t stdio::console::get_rows() const {
|
||||
if(text){
|
||||
if (text) {
|
||||
return t_console.lines();
|
||||
} else {
|
||||
return v_console.lines();
|
||||
@ -51,30 +51,30 @@ size_t stdio::console::get_rows() const {
|
||||
}
|
||||
|
||||
size_t stdio::console::get_columns() const {
|
||||
if(text){
|
||||
if (text) {
|
||||
return t_console.columns();
|
||||
} else {
|
||||
return v_console.columns();
|
||||
}
|
||||
}
|
||||
|
||||
void stdio::console::print(char key){
|
||||
if(key == '\n'){
|
||||
void stdio::console::print(char key) {
|
||||
if (key == '\n') {
|
||||
next_line();
|
||||
} else if(key == '\r'){
|
||||
} else if (key == '\r') {
|
||||
// Ignore \r for now
|
||||
} else if(key == '\b'){
|
||||
} else if (key == '\b') {
|
||||
--current_column;
|
||||
print(' ');
|
||||
--current_column;
|
||||
} else if(key == '\t'){
|
||||
} else if (key == '\t') {
|
||||
print(' ');
|
||||
print(' ');
|
||||
} else {
|
||||
if(text){
|
||||
if (text) {
|
||||
t_console.print_char(current_line, current_column, key);
|
||||
} else {
|
||||
if(active){
|
||||
if (active) {
|
||||
v_console.print_char(current_line, current_column, key);
|
||||
} else {
|
||||
v_console.print_char(buffer, current_line, current_column, key);
|
||||
@ -83,51 +83,51 @@ void stdio::console::print(char key){
|
||||
|
||||
++current_column;
|
||||
|
||||
if(current_column == console::get_columns()){
|
||||
if (current_column == console::get_columns()) {
|
||||
next_line();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stdio::console::wipeout(){
|
||||
if(text){
|
||||
void stdio::console::wipeout() {
|
||||
if (text) {
|
||||
t_console.clear();
|
||||
} else {
|
||||
if(active){
|
||||
if (active) {
|
||||
v_console.clear();
|
||||
} else {
|
||||
v_console.clear(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
current_line = 0;
|
||||
current_line = 0;
|
||||
current_column = 0;
|
||||
}
|
||||
|
||||
void stdio::console::save(){
|
||||
void stdio::console::save() {
|
||||
thor_assert(!text, "save/restore of the text console is not yet supported");
|
||||
|
||||
buffer = v_console.save(buffer);
|
||||
}
|
||||
|
||||
void stdio::console::restore(){
|
||||
void stdio::console::restore() {
|
||||
thor_assert(!text, "save/restore of the text console is not yet supported");
|
||||
|
||||
v_console.restore(buffer);
|
||||
}
|
||||
|
||||
void stdio::console::set_active(bool active){
|
||||
void stdio::console::set_active(bool active) {
|
||||
this->active = active;
|
||||
}
|
||||
|
||||
void stdio::console::next_line(){
|
||||
void stdio::console::next_line() {
|
||||
++current_line;
|
||||
|
||||
if(current_line == console::get_rows()){
|
||||
if(text){
|
||||
if (current_line == console::get_rows()) {
|
||||
if (text) {
|
||||
t_console.scroll_up();
|
||||
} else {
|
||||
if(active){
|
||||
if (active) {
|
||||
v_console.scroll_up();
|
||||
} else {
|
||||
v_console.scroll_up(buffer);
|
||||
|
@ -27,7 +27,7 @@ size_t active_terminal;
|
||||
|
||||
std::array<stdio::virtual_terminal, MAX_TERMINALS> terminals;
|
||||
|
||||
void input_thread(void* data){
|
||||
void input_thread(void* data) {
|
||||
auto& terminal = *reinterpret_cast<stdio::virtual_terminal*>(data);
|
||||
|
||||
auto pid = scheduler::get_pid();
|
||||
@ -35,62 +35,62 @@ void input_thread(void* data){
|
||||
logging::logf(logging::log_level::TRACE, "stdio: Input Thread for terminal %u started (pid:%u)\n", terminal.id, pid);
|
||||
|
||||
bool shift = false;
|
||||
bool alt = false;
|
||||
bool alt = false;
|
||||
|
||||
while(true){
|
||||
while (true) {
|
||||
// Wait for some input
|
||||
scheduler::block_process(pid);
|
||||
|
||||
// Handle keyboard input
|
||||
while(!terminal.keyboard_buffer.empty()){
|
||||
while (!terminal.keyboard_buffer.empty()) {
|
||||
auto key = terminal.keyboard_buffer.pop();
|
||||
|
||||
if(terminal.canonical){
|
||||
if (terminal.canonical) {
|
||||
//Key released
|
||||
if(key & 0x80){
|
||||
if (key & 0x80) {
|
||||
key &= ~(0x80);
|
||||
|
||||
if(alt && key == keyboard::KEY_F1){
|
||||
if (alt && key == keyboard::KEY_F1) {
|
||||
stdio::switch_terminal(0);
|
||||
} else if(alt && key == keyboard::KEY_F2){
|
||||
} else if (alt && key == keyboard::KEY_F2) {
|
||||
stdio::switch_terminal(1);
|
||||
} else if(alt && key == keyboard::KEY_F3){
|
||||
} else if (alt && key == keyboard::KEY_F3) {
|
||||
stdio::switch_terminal(2);
|
||||
}
|
||||
|
||||
if(key == keyboard::KEY_LEFT_SHIFT || key == keyboard::KEY_RIGHT_SHIFT){
|
||||
if (key == keyboard::KEY_LEFT_SHIFT || key == keyboard::KEY_RIGHT_SHIFT) {
|
||||
shift = false;
|
||||
}
|
||||
|
||||
if(key == keyboard::KEY_ALT){
|
||||
if (key == keyboard::KEY_ALT) {
|
||||
alt = false;
|
||||
}
|
||||
}
|
||||
//Key pressed
|
||||
else {
|
||||
if(key == keyboard::KEY_LEFT_SHIFT || key == keyboard::KEY_RIGHT_SHIFT){
|
||||
if (key == keyboard::KEY_LEFT_SHIFT || key == keyboard::KEY_RIGHT_SHIFT) {
|
||||
shift = true;
|
||||
} else if(key == keyboard::KEY_ALT){
|
||||
} else if (key == keyboard::KEY_ALT) {
|
||||
alt = true;
|
||||
} else if(key == keyboard::KEY_BACKSPACE){
|
||||
if(!terminal.input_buffer.empty()){
|
||||
} else if (key == keyboard::KEY_BACKSPACE) {
|
||||
if (!terminal.input_buffer.empty()) {
|
||||
terminal.input_buffer.pop_last();
|
||||
terminal.print('\b');
|
||||
}
|
||||
} else {
|
||||
auto qwertz_key =
|
||||
shift
|
||||
? keyboard::shift_key_to_ascii(key)
|
||||
: keyboard::key_to_ascii(key);
|
||||
? keyboard::shift_key_to_ascii(key)
|
||||
: keyboard::key_to_ascii(key);
|
||||
|
||||
if(qwertz_key){
|
||||
if (qwertz_key) {
|
||||
terminal.input_buffer.push(qwertz_key);
|
||||
|
||||
terminal.print(qwertz_key);
|
||||
|
||||
if(qwertz_key == '\n'){
|
||||
if (qwertz_key == '\n') {
|
||||
// Transfer current line to the canonical buffer
|
||||
while(!terminal.input_buffer.empty()){
|
||||
while (!terminal.input_buffer.empty()) {
|
||||
terminal.canonical_buffer.push(terminal.input_buffer.pop());
|
||||
}
|
||||
|
||||
@ -112,10 +112,10 @@ void input_thread(void* data){
|
||||
}
|
||||
|
||||
// Handle mouse input
|
||||
while(!terminal.mouse_buffer.empty()){
|
||||
while (!terminal.mouse_buffer.empty()) {
|
||||
auto key = terminal.mouse_buffer.pop();
|
||||
|
||||
if(!terminal.canonical && terminal.mouse){
|
||||
if (!terminal.canonical && terminal.is_mouse()) {
|
||||
terminal.raw_buffer.push(key);
|
||||
|
||||
terminal.input_queue.notify_one();
|
||||
@ -128,10 +128,10 @@ void input_thread(void* data){
|
||||
|
||||
} //end of anonymous namespace
|
||||
|
||||
void stdio::init_terminals(){
|
||||
void stdio::init_terminals() {
|
||||
size_t id = 0;
|
||||
|
||||
for(auto& terminal : terminals){
|
||||
for (auto& terminal : terminals) {
|
||||
terminal.id = id++;
|
||||
terminal.active = false;
|
||||
terminal.canonical = true;
|
||||
@ -140,25 +140,25 @@ void stdio::init_terminals(){
|
||||
|
||||
// Initialize the active terminal
|
||||
|
||||
active_terminal = 0;
|
||||
active_terminal = 0;
|
||||
terminals[active_terminal].active = true;
|
||||
terminals[active_terminal].get_console().set_active(true);
|
||||
}
|
||||
|
||||
void stdio::register_devices(){
|
||||
for(auto& terminal : terminals){
|
||||
void stdio::register_devices() {
|
||||
for (auto& terminal : terminals) {
|
||||
std::string name = std::string("tty") + std::to_string(terminal.id);
|
||||
|
||||
devfs::register_device("/dev/", name, devfs::device_type::CHAR_DEVICE, tty_driver, &terminal);
|
||||
}
|
||||
}
|
||||
|
||||
void stdio::finalize(){
|
||||
for(auto& terminal : terminals){
|
||||
void stdio::finalize() {
|
||||
for (auto& terminal : terminals) {
|
||||
auto* user_stack = new char[scheduler::user_stack_size];
|
||||
auto* kernel_stack = new char[scheduler::kernel_stack_size];
|
||||
|
||||
auto& input_process = scheduler::create_kernel_task_args("tty_input", user_stack, kernel_stack, &input_thread, &terminal);
|
||||
auto& input_process = scheduler::create_kernel_task_args("tty_input", user_stack, kernel_stack, &input_thread, &terminal);
|
||||
input_process.ppid = 1;
|
||||
input_process.priority = scheduler::DEFAULT_PRIORITY;
|
||||
|
||||
@ -172,22 +172,22 @@ void stdio::finalize(){
|
||||
}
|
||||
}
|
||||
|
||||
size_t stdio::terminals_count(){
|
||||
size_t stdio::terminals_count() {
|
||||
return MAX_TERMINALS;
|
||||
}
|
||||
|
||||
stdio::virtual_terminal& stdio::get_active_terminal(){
|
||||
stdio::virtual_terminal& stdio::get_active_terminal() {
|
||||
return terminals[active_terminal];
|
||||
}
|
||||
|
||||
stdio::virtual_terminal& stdio::get_terminal(size_t id){
|
||||
stdio::virtual_terminal& stdio::get_terminal(size_t id) {
|
||||
thor_assert(id < MAX_TERMINALS, "Out of bound tty");
|
||||
|
||||
return terminals[id];
|
||||
}
|
||||
|
||||
void stdio::switch_terminal(size_t id){
|
||||
if(active_terminal != id){
|
||||
void stdio::switch_terminal(size_t id) {
|
||||
if (active_terminal != id) {
|
||||
logging::logf(logging::log_level::TRACE, "stdio: Switch activate virtual terminal %u\n", id);
|
||||
|
||||
// Effectively switch the terminal
|
||||
|
@ -17,12 +17,12 @@
|
||||
|
||||
#include "print.hpp"
|
||||
|
||||
void stdio::virtual_terminal::print(char key){
|
||||
void stdio::virtual_terminal::print(char key) {
|
||||
cons.print(key);
|
||||
}
|
||||
|
||||
void stdio::virtual_terminal::send_input(char key){
|
||||
if(!input_thread_pid){
|
||||
void stdio::virtual_terminal::send_input(char key) {
|
||||
if (!input_thread_pid) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -34,8 +34,8 @@ void stdio::virtual_terminal::send_input(char key){
|
||||
scheduler::unblock_process_hint(input_thread_pid);
|
||||
}
|
||||
|
||||
void stdio::virtual_terminal::send_mouse_input(std::keycode key){
|
||||
if(!input_thread_pid){
|
||||
void stdio::virtual_terminal::send_mouse_input(std::keycode key) {
|
||||
if (!input_thread_pid) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -47,16 +47,16 @@ void stdio::virtual_terminal::send_mouse_input(std::keycode key){
|
||||
scheduler::unblock_process_hint(input_thread_pid);
|
||||
}
|
||||
|
||||
size_t stdio::virtual_terminal::read_input_can(char* buffer, size_t max){
|
||||
size_t stdio::virtual_terminal::read_input_can(char* buffer, size_t max) {
|
||||
size_t read = 0;
|
||||
|
||||
while(true){
|
||||
while(!canonical_buffer.empty()){
|
||||
while (true) {
|
||||
while (!canonical_buffer.empty()) {
|
||||
auto c = canonical_buffer.pop();
|
||||
|
||||
buffer[read++] = c;
|
||||
|
||||
if(read >= max || c == '\n'){
|
||||
if (read >= max || c == '\n') {
|
||||
return read;
|
||||
}
|
||||
}
|
||||
@ -66,45 +66,45 @@ size_t stdio::virtual_terminal::read_input_can(char* buffer, size_t max){
|
||||
}
|
||||
|
||||
// TODO In case of max < read, the timeout is not respected
|
||||
size_t stdio::virtual_terminal::read_input_can(char* buffer, size_t max, size_t ms){
|
||||
size_t stdio::virtual_terminal::read_input_can(char* buffer, size_t max, size_t ms) {
|
||||
size_t read = 0;
|
||||
|
||||
while(true){
|
||||
while(!canonical_buffer.empty()){
|
||||
while (true) {
|
||||
while (!canonical_buffer.empty()) {
|
||||
auto c = canonical_buffer.pop();
|
||||
|
||||
buffer[read++] = c;
|
||||
|
||||
if(read >= max || c == '\n'){
|
||||
if (read >= max || c == '\n') {
|
||||
return read;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ms){
|
||||
if (!ms) {
|
||||
return read;
|
||||
}
|
||||
|
||||
if(!input_queue.wait_for(ms)){
|
||||
if (!input_queue.wait_for(ms)) {
|
||||
return read;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t stdio::virtual_terminal::read_input_raw(){
|
||||
if(raw_buffer.empty()){
|
||||
size_t stdio::virtual_terminal::read_input_raw() {
|
||||
if (raw_buffer.empty()) {
|
||||
input_queue.wait();
|
||||
}
|
||||
|
||||
return raw_buffer.pop();
|
||||
}
|
||||
|
||||
size_t stdio::virtual_terminal::read_input_raw(size_t ms){
|
||||
if(raw_buffer.empty()){
|
||||
if(!ms){
|
||||
size_t stdio::virtual_terminal::read_input_raw(size_t ms) {
|
||||
if (raw_buffer.empty()) {
|
||||
if (!ms) {
|
||||
return static_cast<size_t>(std::keycode::TIMEOUT);
|
||||
}
|
||||
|
||||
if(!input_queue.wait_for(ms)){
|
||||
if (!input_queue.wait_for(ms)) {
|
||||
return static_cast<size_t>(std::keycode::TIMEOUT);
|
||||
}
|
||||
}
|
||||
@ -114,13 +114,13 @@ size_t stdio::virtual_terminal::read_input_raw(size_t ms){
|
||||
return raw_buffer.pop();
|
||||
}
|
||||
|
||||
void stdio::virtual_terminal::set_canonical(bool can){
|
||||
void stdio::virtual_terminal::set_canonical(bool can) {
|
||||
logging::logf(logging::log_level::TRACE, "Switched terminal %u canonical mode from %u to %u\n", id, uint64_t(canonical), uint64_t(can));
|
||||
|
||||
canonical = can;
|
||||
}
|
||||
|
||||
void stdio::virtual_terminal::set_mouse(bool m){
|
||||
void stdio::virtual_terminal::set_mouse(bool m) {
|
||||
logging::logf(logging::log_level::TRACE, "Switched terminal %u mouse handling mode from %u to %u\n", id, uint64_t(mouse), uint64_t(m));
|
||||
|
||||
mouse = m;
|
||||
@ -130,8 +130,12 @@ bool stdio::virtual_terminal::is_canonical() const {
|
||||
return canonical;
|
||||
}
|
||||
|
||||
void stdio::virtual_terminal::set_active(bool active){
|
||||
if(this->active == active){
|
||||
bool stdio::virtual_terminal::is_mouse() const {
|
||||
return mouse;
|
||||
}
|
||||
|
||||
void stdio::virtual_terminal::set_active(bool active) {
|
||||
if (this->active == active) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -139,13 +143,13 @@ void stdio::virtual_terminal::set_active(bool active){
|
||||
|
||||
cons.set_active(active);
|
||||
|
||||
if(active){
|
||||
if (active) {
|
||||
cons.restore();
|
||||
} else {
|
||||
cons.save();
|
||||
}
|
||||
}
|
||||
|
||||
stdio::console& stdio::virtual_terminal::get_console(){
|
||||
stdio::console& stdio::virtual_terminal::get_console() {
|
||||
return cons;
|
||||
}
|
||||
|
@ -12,70 +12,70 @@
|
||||
namespace {
|
||||
|
||||
enum vga_color {
|
||||
BLACK = 0,
|
||||
BLUE = 1,
|
||||
GREEN = 2,
|
||||
CYAN = 3,
|
||||
RED = 4,
|
||||
MAGENTA = 5,
|
||||
BROWN = 6,
|
||||
LIGHT_GREY = 7,
|
||||
DARK_GREY = 8,
|
||||
LIGHT_BLUE = 9,
|
||||
LIGHT_GREEN = 10,
|
||||
LIGHT_CYAN = 11,
|
||||
LIGHT_RED = 12,
|
||||
BLACK = 0,
|
||||
BLUE = 1,
|
||||
GREEN = 2,
|
||||
CYAN = 3,
|
||||
RED = 4,
|
||||
MAGENTA = 5,
|
||||
BROWN = 6,
|
||||
LIGHT_GREY = 7,
|
||||
DARK_GREY = 8,
|
||||
LIGHT_BLUE = 9,
|
||||
LIGHT_GREEN = 10,
|
||||
LIGHT_CYAN = 11,
|
||||
LIGHT_RED = 12,
|
||||
LIGHT_MAGENTA = 13,
|
||||
LIGHT_BROWN = 14,
|
||||
WHITE = 15,
|
||||
LIGHT_BROWN = 14,
|
||||
WHITE = 15,
|
||||
};
|
||||
|
||||
uint8_t make_color(vga_color fg, vga_color bg){
|
||||
uint8_t make_color(vga_color fg, vga_color bg) {
|
||||
return fg | bg << 4;
|
||||
}
|
||||
|
||||
uint16_t make_vga_entry(char c, uint8_t color){
|
||||
uint16_t c16 = c;
|
||||
uint16_t make_vga_entry(char c, uint8_t color) {
|
||||
uint16_t c16 = c;
|
||||
uint16_t color16 = color;
|
||||
return c16 | color16 << 8;
|
||||
}
|
||||
|
||||
} //end of anonymous namespace
|
||||
|
||||
void text_console::init(){
|
||||
void text_console::init() {
|
||||
//Nothing special to init
|
||||
}
|
||||
|
||||
size_t text_console::lines(){
|
||||
size_t text_console::lines() {
|
||||
return 25;
|
||||
}
|
||||
|
||||
size_t text_console::columns(){
|
||||
size_t text_console::columns() {
|
||||
return 80;
|
||||
}
|
||||
|
||||
void text_console::clear(){
|
||||
for(int line = 0; line < 25; ++line){
|
||||
for(uint64_t column = 0; column < 80; ++column){
|
||||
void text_console::clear() {
|
||||
for (int line = 0; line < 25; ++line) {
|
||||
for (uint64_t column = 0; column < 80; ++column) {
|
||||
print_char(line, column, ' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void text_console::scroll_up(){
|
||||
void text_console::scroll_up() {
|
||||
auto vga_buffer_fast = reinterpret_cast<uint64_t*>(0x0B8000);
|
||||
auto destination = vga_buffer_fast;
|
||||
auto source = &vga_buffer_fast[20];
|
||||
auto destination = vga_buffer_fast;
|
||||
auto source = &vga_buffer_fast[20];
|
||||
|
||||
std::copy_n(source, 24 * 20, destination);
|
||||
|
||||
auto vga_buffer = reinterpret_cast<uint16_t*>(0x0B8000);
|
||||
for(uint64_t i = 0; i < 80; ++i){
|
||||
for (uint64_t i = 0; i < 80; ++i) {
|
||||
vga_buffer[24 * 80 + i] = make_vga_entry(' ', make_color(WHITE, BLACK));
|
||||
}
|
||||
}
|
||||
|
||||
void text_console::print_char(size_t line, size_t column, char c){
|
||||
void text_console::print_char(size_t line, size_t column, char c) {
|
||||
uint16_t* vga_buffer = reinterpret_cast<uint16_t*>(0x0B8000);
|
||||
|
||||
vga_buffer[line * 80 + column] = make_vga_entry(c, make_color(WHITE, BLACK));
|
||||
|
Loading…
x
Reference in New Issue
Block a user