- More implementations and dependencies for Linux Wayland support

This commit is contained in:
2025-07-26 20:57:25 -04:00
parent 7ea2710ee0
commit 7493b5252a
78 changed files with 3733 additions and 316 deletions

View File

@@ -0,0 +1,37 @@
// =====================================================================================================================
// 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 <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/platform/interface/displaydev.h>
namespace fennec
{
displaydev::displaydev(platform* platform)
: _platform(platform)
, _context(nullptr)
, _config {
.format = {
.depth = 24,
.r = 8,
.g = 8,
.b = 8
}
} {
}
}

View File

@@ -16,38 +16,15 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/platform/linux/wayland/display.h>
#include <fennec/platform/linux/wayland/lib/sym_def.h>
#include <fennec/platform/linux/wayland/lib/dyn.h>
#include <fennec/platform/interface/gfxcontext.h>
namespace fennec
{
wayland_display::wayland_display(linux_platform* platform)
: display()
, _handle()
, _platform(platform) {
libwayland::load_symbols(_platform);
_handle = wl_display_connect(nullptr);
gfxcontext::gfxcontext(displaydev* device)
: _device(device) {
}
wayland_display::wayland_display(linux_platform* platform, const cstring& drv)
: display()
, _handle()
, _platform(platform) {
libwayland::load_symbols(_platform);
_handle = wl_display_connect(drv);
}
wayland_display::~wayland_display() {
wl_display_disconnect(_handle);
libwayland::unload_symbols(_platform);
_handle = nullptr;
_platform = nullptr;
}
bool wayland_display::connected() const {
return _handle != nullptr;
}
}

View File

@@ -0,0 +1,28 @@
// =====================================================================================================================
// 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 <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/platform/interface/gfxsurface.h>
namespace fennec
{
gfxsurface::gfxsurface(window* window, gfxcontext* context)
: _window(window), _context(context) {
}
}

View File

@@ -27,8 +27,7 @@ string platform::get_environment_variable(const cstring& var) {
return string(val, strlen(val));
}
platform::platform(user t) {
_config.type = t;
platform::platform() {
}
}

View File

@@ -21,15 +21,10 @@
namespace fennec
{
window::window(display* display, window* parent, bool modal)
window::window(displaydev* display, window* parent)
: _display(display)
, _parent(parent)
, _config() {
bool child = parent != nullptr;
assert(!modal || child, "Attempted to create non-child modal window.");
_config.flags |= child ? flags_child : flags_none;
_config.flags |= modal ? flags_modal : flags_none;
}
}

View File

@@ -22,24 +22,20 @@
#ifdef FENNEC_LIB_WAYLAND
#include <fennec/platform/linux/wayland/lib/dyn.h>
#include <fennec/platform/linux/wayland/display.h>
#include <fennec/platform/linux/wayland/displaydev.h>
#endif
namespace fennec
{
linux_platform::linux_platform(user _type)
: platform(_type)
linux_platform::linux_platform()
: platform()
, _display_driver(display_none) {
switch (_type) {
case user::client: {
_runtime_client_checks();
return;
}
case user::server: {
_runtime_server_checks();
}
}
#if FENNEC_BUILD_SERVER
_runtime_server_checks();
#else
_runtime_client_checks();
#endif
}
linux_platform::~linux_platform() {
@@ -72,7 +68,17 @@ platform::function_pointer linux_platform::find_symbol(shared_object* hndl, cons
return (function_pointer)symbol;
}
display* linux_platform::get_display() {
platform::global linux_platform::find_global(shared_object* hndl, const cstring& name) {
string _name = name;
void* symbol = dlsym(hndl, _name);
if (symbol == nullptr) {
_name = '_' + _name;
symbol = dlsym(hndl, _name);
}
return symbol;
}
displaydev* linux_platform::get_display() {
return _display;
}
@@ -82,7 +88,7 @@ void linux_platform::_runtime_client_checks() {
_display_driver = display_wayland;
_display = new wayland_display(this);
libwayland::unload_symbols(this); // Doesn't actually unload symbols, just resets ref counter to only consider
// the created display
// the created display
}
#endif
assertf(_display != nullptr, "failed to find suitable display driver");

View File

@@ -0,0 +1,98 @@
// =====================================================================================================================
// 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 <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/platform/linux/wayland/displaydev.h>
#include <fennec/platform/linux/wayland/window.h>
#include <fennec/platform/linux/wayland/lib/dyn.h>
#include <fennec/platform/linux/wayland/lib/wayland-client.h>
namespace fennec
{
wayland_display::wayland_display(linux_platform* platform)
: wayland_display(platform, nullptr) {
}
wayland_display::wayland_display(linux_platform* platform, const cstring& drv)
: displaydev(platform)
, _handle(nullptr)
, _registry(nullptr)
, _compositor(nullptr) {
static constexpr wl_registry_listener listener = {
listen_global, listen_global_remove
};
// Load libwayland.so
libwayland::load_symbols(get_platform<linux_platform>());
// Get handles
_handle = wl_display_connect(drv);
_registry = wl_display_get_registry(_handle);
wl_registry_add_listener(_registry, &listener, this);
}
wayland_display::~wayland_display() {
wl_registry_destroy(_registry);
wl_display_flush(_handle);
wl_display_disconnect(_handle);
libwayland::unload_symbols(get_platform<linux_platform>());
_handle = nullptr;
_platform = nullptr;
for (const auto it : _windows) {
delete it;
}
}
bool wayland_display::connected() const {
return _handle != nullptr;
}
window* wayland_display::create_window() {
_windows.push_back(new wayland_window(this, nullptr));
return (window*)(_windows.back());
}
void wayland_display::listen_global(void* data, wl_registry* registry, uint32_t name, const char* itfc, uint32_t version) {
static constexpr wl_seat_listener seat_listener = {
listen_seat, nullptr
};
wayland_display* device = static_cast<wayland_display*>(data);
const cstring interface = cstring(itfc, strlen(itfc) + 1);
if (interface == "wl_compositor") {
device->_compositor = static_cast<wl_compositor*>(wl_registry_bind(registry, name, wl_compositor_interface, version));
} else if (interface == "wl_shell") {
device->_shell = static_cast<wl_shell*>(wl_registry_bind(registry, name, wl_shell_interface, version));
} else if (interface == "wl_seat") {
device->_seat = static_cast<wl_seat*>(wl_registry_bind(registry, name, wl_seat_interface, version));
wl_seat_add_listener(device->_seat, &seat_listener, device);
}
}
void wayland_display::listen_global_remove(void*, wl_registry*, uint32_t) {
}
void wayland_display::listen_seat(void*, wl_seat*, uint32_t) {
}
}

View File

@@ -16,7 +16,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/platform/linux/wayland/lib/sym_def.h>
#include <fennec/platform/linux/wayland/lib/wayland-client.h>
#include <fennec/platform/linux/wayland/lib/dyn.h>
namespace fennec
@@ -31,7 +31,6 @@ static int _load_count = 0;
// Create private variables
#define FENNEC_LIB(lib) static shared_lib _FENNEC_LIB_##lib = { nullptr, FENNEC_LIB_##lib };
#define FENNEC_SYMBOL(...)
#include <fennec/platform/linux/wayland/lib/sym.h>
bool load_symbols(linux_platform* platform) {
@@ -39,14 +38,20 @@ bool load_symbols(linux_platform* platform) {
return true;
}
shared_lib* current_lib = nullptr;
#define FENNEC_LIB(lib) _FENNEC_LIB_##lib._lib = platform->load_object(_FENNEC_LIB_##lib._name); \
FENNEC_HAS_LIB_##lib = _FENNEC_LIB_##lib._lib != nullptr; \
if(not FENNEC_HAS_LIB_##lib) { \
unload_symbols(platform); \
return false; \
} \
shared_lib& current_lib = _FENNEC_LIB_##lib;
#define FENNEC_SYMBOL(ret, fn, ...) fn = (sym_##fn)(platform->find_symbol(current_lib._lib, #fn));
current_lib = &_FENNEC_LIB_##lib;
#define FENNEC_SYMBOL(ret, fn, ...) fn = (sym_##fn)(platform->find_symbol(current_lib->_lib, #fn)); \
assertf(fn != nullptr, "Failed to find symbol: " #fn);
#define FENNEC_GLOBAL(type, name) name = (type*)(platform->find_symbol(current_lib->_lib, #name)); \
assertf(name != nullptr, "Failed to find global: " #name);
#include <fennec/platform/linux/wayland/lib/sym.h>
return true;
@@ -60,6 +65,7 @@ void unload_symbols(linux_platform* platform) {
#define FENNEC_LIB(lib) platform->unload_object(_FENNEC_LIB_##lib._lib); \
_FENNEC_LIB_##lib._lib = nullptr;
#define FENNEC_SYMBOL(ret, fn, ...) fn = nullptr;
#define FENNEC_GLOBAL(type, name) name = nullptr;
#include <fennec/platform/linux/wayland/lib/sym.h>
}

View File

@@ -0,0 +1,86 @@
// =====================================================================================================================
// 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 <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/platform/linux/wayland/displaydev.h>
#include <fennec/platform/linux/wayland/window.h>
#include <EGL/egl.h>
namespace fennec
{
bool wayland_window::running() {
return false;
}
void wayland_window::configure(const config& config) {
assertf(running() == false, "Attempted to Configure Running Window.");
_config = config;
}
bool wayland_window::initialize(bool modal) {
assertf(_config, "Attempted to Initialize a Window Without Configuration");
if (not _config) {
return true;
}
_config->flags &= ~flags_modal & ~flags_child;
if (_parent != nullptr) {
_config->flags |= flags_child;
if (modal) {
_config->flags |= flags_modal;
}
}
_surface = wl_compositor_create_surface(get_display<wayland_display>()->get_compositor());
_shell = wl_shell_get_shell_surface(get_display<wayland_display>()->get_shell(), _surface);
return false;
}
bool wayland_window::shutdown() {
wl_shell_surface_destroy(_shell);
wl_surface_destroy(_surface);
return false;
}
bool wayland_window::set_title(const cstring&) { return true; }
bool wayland_window::set_title(const string&) { return true; }
bool wayland_window::set_width(size_t) { return true; }
bool wayland_window::set_height(size_t) { return true; }
bool wayland_window::set_size(size_t, size_t) { return true; }
bool wayland_window::set_fullscreen_mode(fullscreen_mode) { return true; }
bool wayland_window::set_resizable(bool) { return true; }
bool wayland_window::grab_keyboard(bool) { return true; }
bool wayland_window::grab_mouse(bool) { return true; }
bool wayland_window::block_screensaver(bool) { return true; }
wayland_window::wayland_window(wayland_display* display, wayland_window* parent)
: window(display, parent)
, _surface(nullptr)
, _shell(nullptr)
, _callback(nullptr) {
}
wayland_window::~wayland_window() {
}
}