Serenity Operating System
at master 96 lines 2.9 kB view raw
1/* 2 * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/Singleton.h> 8#include <Kernel/CommandLine.h> 9#include <Kernel/Debug.h> 10#include <Kernel/Devices/DeviceManagement.h> 11#include <Kernel/Graphics/GraphicsManagement.h> 12#include <Kernel/Panic.h> 13#include <Kernel/Sections.h> 14#include <Kernel/TTY/ConsoleManagement.h> 15 16namespace Kernel { 17 18static Singleton<ConsoleManagement> s_the; 19 20void ConsoleManagement::resolution_was_changed() 21{ 22 for (auto& console : m_consoles) { 23 console->refresh_after_resolution_change(); 24 } 25} 26 27bool ConsoleManagement::is_initialized() 28{ 29 if (!s_the.is_initialized()) 30 return false; 31 if (s_the->m_consoles.is_empty()) 32 return false; 33 if (!s_the->m_active_console) 34 return false; 35 return true; 36} 37 38ConsoleManagement& ConsoleManagement::the() 39{ 40 return *s_the; 41} 42 43UNMAP_AFTER_INIT ConsoleManagement::ConsoleManagement() 44{ 45} 46 47UNMAP_AFTER_INIT void ConsoleManagement::initialize() 48{ 49 for (size_t index = 0; index < s_max_virtual_consoles; index++) { 50 // FIXME: Better determine the debug TTY we chose... 51 if (index == 1) { 52 VERIFY(DeviceManagement::the().is_console_device_attached()); 53 m_consoles.append(VirtualConsole::create_with_preset_log(index, DeviceManagement::the().console_device().logbuffer())); 54 continue; 55 } 56 m_consoles.append(VirtualConsole::create(index)); 57 } 58 // Note: By default the active console is the first one. 59 auto tty_number = kernel_command_line().switch_to_tty(); 60 if (tty_number > m_consoles.size()) { 61 PANIC("Switch to tty value is invalid: {} ", tty_number); 62 } 63 m_active_console = m_consoles[tty_number]; 64 SpinlockLocker lock(m_lock); 65 m_active_console->set_active(true); 66 if (!m_active_console->is_graphical()) 67 m_active_console->clear(); 68} 69 70void ConsoleManagement::switch_to(unsigned index) 71{ 72 SpinlockLocker lock(m_lock); 73 VERIFY(m_active_console); 74 VERIFY(index < m_consoles.size()); 75 if (m_active_console->index() == index) 76 return; 77 78 bool was_graphical = m_active_console->is_graphical(); 79 m_active_console->set_active(false); 80 m_active_console = m_consoles[index]; 81 dbgln_if(VIRTUAL_CONSOLE_DEBUG, "Console: Switch to {}", index); 82 83 // Before setting current console to be "active", switch between graphical mode to "textual" mode 84 // if needed. This will ensure we clear the screen and also that WindowServer won't print anything 85 // in between. 86 if (m_active_console->is_graphical() && !was_graphical) { 87 m_active_console->set_active(true); 88 GraphicsManagement::the().activate_graphical_mode(); 89 return; 90 } else if (!m_active_console->is_graphical() && was_graphical) { 91 GraphicsManagement::the().deactivate_graphical_mode(); 92 } 93 m_active_console->set_active(true); 94} 95 96}