// ===================================================================================================================== // fennec, a free and open source game engine // Copyright © 2025 Medusa Slockbower // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // ===================================================================================================================== #include #include #include #include #include #include namespace fennec { window_manager::window_manager(platform* platform) : _platform(platform) { } window_manager::~window_manager() { shutdown(); } void window_manager::initialize() { if (_display) { return; } // Get the list of registered display servers display_server::entrylist_t display_servers = display_server::get_type_list(); // Find first valid server while (not display_servers.empty()) { display_server::entry it = display_servers.front(); display_servers.pop(); unique_ptr server = unique_ptr(it.ctor(_platform)); server->connect(); if (server->connected()) { logger::log(format("Selected {} for the display server.", server->get_type().name())); _display = move(server); break; } } assertf(_display, "Failed to select a display server!"); _thread = thread::current(); logger::log(format("Initializing Window Manager on thread: {:#016x}.", _thread)); } void window_manager::shutdown() { if (not _display) { return; } assertf(_thread == thread::current(), "Attempted to shutdown Window Manager on a different thread!"); lock_guard guard(_lock); // Cleanup Windows for (auto& window : _windows) { window->shutdown(); window.reset(); } _windows.clear(); // Cleanup Display Server _display->disconnect(); _display.reset(); } void window_manager::dispatch() { if (not _display) { return; } assertf(_thread == thread::current(), "Attempted to dispatch Window Manager on a different thread!"); lock_guard guard(_lock); _display->dispatch(); } window_manager::window_id window_manager::create_window(const window::config& config, window_id parent) { if (not _display) { return nullid; } assertf(_thread == thread::current(), "Attempted to create a window on a different thread!"); lock_guard guard(_lock); window* p = parent == nullid ? nullptr : _windows[parent].get(); return _windows.emplace(_display->create_window(config, p)); } void window_manager::begin(window_id window) { if (not _display) { return; } assertf(_thread == thread::current(), "Attempted to set window context on a different thread!"); lock_guard guard(_lock); _windows[window]->begin_frame(); } void window_manager::end(window_id window) { if (not _display) { return; } assertf(_thread == thread::current(), "Attempted to set window context on a different thread!"); lock_guard guard(_lock); _windows[window]->end_frame(); } } // fennec