- Switched to SDL for main branch, will revisit custom implementation later.

This commit is contained in:
2025-08-23 20:09:53 -04:00
parent 086c73f058
commit e1eaf97961
43 changed files with 133 additions and 16267 deletions

3
.gitmodules vendored
View File

@@ -1,3 +1,6 @@
[submodule "external/cpptrace"]
path = external/cpptrace
url = https://github.com/jeremy-rifkin/cpptrace.git
[submodule "external/SDL"]
path = external/SDL
url = https://github.com/libsdl-org/SDL

View File

@@ -17,14 +17,16 @@
# ======================================================================================================================
cmake_minimum_required(VERSION 3.30)
project(fennec)
set(FENNEC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
# External dependencies should be loaded here
add_subdirectory(external/cpptrace)
include("${FENNEC_SOURCE_DIR}/cmake/sdl.cmake")
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_C_STANDARD 23)
set(FENNEC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
add_custom_target(fennec-dependencies
COMMAND ${CMAKE_COMMAND} -E echo "Running dependencies."
@@ -43,6 +45,10 @@ macro(fennec_add_link_libraries)
list(APPEND FENNEC_LINK_LIBRARIES ${ARGN})
endmacro()
macro(fennec_add_link_options)
list(APPEND FENNEC_PRIVATE_LINK_OPTIONS ${ARGN})
endmacro()
# include scripts
include("${FENNEC_SOURCE_DIR}/cmake/version.cmake")
include("${FENNEC_SOURCE_DIR}/cmake/platform.cmake")
@@ -62,7 +68,7 @@ include_directories(${FENNEC_SOURCE_DIR}/include)
# Metaprogramming is a dependency for generating various type info before compilation of the engine.
add_subdirectory(metaprogramming)
# Specify where to send libraries and executables
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${FENNEC_SOURCE_DIR}/lib/${FENNEC_BUILD_NAME})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${FENNEC_SOURCE_DIR}/lib/${FENNEC_BUILD_NAME})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${FENNEC_SOURCE_DIR}/bin/${FENNEC_BUILD_NAME})
@@ -212,14 +218,13 @@ add_library(fennec STATIC
include/fennec/platform/interface/fwd.h
include/fennec/platform/interface/platform.h source/platform/interface/platform.cpp
include/fennec/platform/interface/display.h source/platform/interface/display.cpp
include/fennec/platform/interface/gfxcontext.h
include/fennec/platform/interface/gfxsurface.h
# EXTRA SOURCES ========================================================================================================
# EXTRA SOURCES ========================================================================================================
${FENNEC_EXTRA_SOURCES}
include/fennec/platform/interface/window.h
include/fennec/platform/sdl/sdlwindow.h
)
add_dependencies(fennec metaprogramming fennec-dependencies)
@@ -237,8 +242,12 @@ target_link_libraries(fennec PRIVATE
${FENNEC_LINK_LIBRARIES}
cpptrace::cpptrace
SDL3::SDL3-shared
)
add_custom_command(TARGET fennec POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_LINKER_FILE:SDL3::SDL3-shared> ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
# DOXYGEN ==============================================================================================================

View File

@@ -20,6 +20,6 @@
add_compile_options("-mxsave" "-Wall" "-Wextra" "-pedantic" "-Werror")
set(FENNEC_PRIVATE_LINK_OPTIONS "-nostdlib" "-fno-exceptions" "-fno-rtti" "-fdiagnostics-all-candidates")
fennec_add_link_options("-nostdlib" "-fno-exceptions" "-fno-rtti" "-fdiagnostics-all-candidates")
list(APPEND FENNEC_COMPILE_DEFINITIONS _GLIBCXX_INCLUDE_NEXT_C_HEADERS=1 FENNEC_COMPILER_GCC=1 FENNEC_NO_INLINE=[[gnu::noinline]])
fennec_add_definitions(_GLIBCXX_INCLUDE_NEXT_C_HEADERS=1 FENNEC_COMPILER_GCC=1 FENNEC_NO_INLINE=[[gnu::noinline]])

View File

@@ -34,9 +34,6 @@ macro(fennec_check_platform)
)
if(FENNEC_USER_CLIENT)
include("${FENNEC_SOURCE_DIR}/cmake/wayland.cmake")
fennec_check_wayland()
fennec_init_graphics()
endif()

View File

@@ -31,27 +31,4 @@ if(TARGET OpenGL::GL AND TARGET GLEW::GLEW)
fennec_add_definitions(FENNEC_GRAPHICS_OPENGL=1)
else()
message(FATAL_ERROR "No Suitable OpenGL implementation found.")
endif()
if(FENNEC_GRAPHICS_WANT_EGL)
if(NOT TARGET OpenGL::EGL)
message(FATAL_ERROR "EGL Library not found.")
endif()
message(STATUS "Found EGL: ${OPENGL_egl_LIBRARY}")
fennec_add_link_libraries(OpenGL::EGL)
fennec_add_definitions(FENNEC_GRAPHICS_EGL=1)
fennec_add_sources(
include/fennec/platform/opengl/lib/fwd.h
include/fennec/platform/opengl/lib/enum.h
include/fennec/platform/opengl/lib/buffer.h
include/fennec/platform/opengl/lib/texture.h
include/fennec/platform/opengl/lib/vertex_array.h
include/fennec/platform/opengl/egl/fwd.h
include/fennec/platform/opengl/egl/context.h source/platform/opengl/egl/context.cpp
include/fennec/platform/opengl/egl/surface.h source/platform/opengl/egl/surface.cpp
)
endif()

21
cmake/sdl.cmake Normal file
View File

@@ -0,0 +1,21 @@
# ======================================================================================================================
# 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/>.
# ======================================================================================================================
set(SDL_AUDIO OFF)
set(SDL_RENDER OFF)
add_subdirectory(external/SDL)

View File

@@ -1,122 +0,0 @@
# ======================================================================================================================
# 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/>.
# ======================================================================================================================
# https://gist.github.com/mariobadr/acc3c8adf4b4e722705be38c3deac59a
# this script finds libwayland and dependencies
# some of this code is based on SDL3's use of wayland-scanner
macro(fennec_wayland_get_header _SCANNER _XML _FILE)
set(_WAYLAND_PROT_H_CODE "${WAYLAND_HEADERS_DIR}/${_FILE}-client-protocols.h")
set(_WAYLAND_PROT_C_CODE "${WAYLAND_SOURCES_DIR}/${_FILE}-client.c")
execute_process(
COMMAND ${_SCANNER} client-header "${_XML}" "${_WAYLAND_PROT_H_CODE}"
)
execute_process(
COMMAND ${_SCANNER} private-code "${_XML}" "${_WAYLAND_PROT_C_CODE}"
)
fennec_add_sources(${_WAYLAND_PROT_C_CODE} ${_WAYLAND_PROT_H_CODE})
endmacro()
macro(fennec_check_wayland)
set(WAYLAND_CLIENT_FOUND 0)
find_path(
WAYLAND_CLIENT_INCLUDE_DIR
NAMES wayland-client.h
)
find_library(
WAYLAND_CLIENT_LIBRARY
NAMES wayland-client libwayland-client
)
find_program(WAYLAND_SCANNER NAMES wayland-scanner)
# EGL is required
find_path(
WAYLAND_EGL_INCLUDE_DIR
NAMES wayland-egl.h
)
find_library(
WAYLAND_EGL_LIBRARY
NAMES wayland-egl libwayland-egl
)
if( (WAYLAND_CLIENT_INCLUDE_DIR AND WAYLAND_CLIENT_LIBRARY AND WAYLAND_SCANNER)
AND (WAYLAND_EGL_INCLUDE_DIR AND WAYLAND_EGL_LIBRARY))
message(STATUS "Found Wayland: ${WAYLAND_CLIENT_LIBRARY}")
set(WAYLAND_PROTOCOLS_DIR ${FENNEC_SOURCE_DIR}/include/fennec/platform/linux/wayland/lib/protocols)
set(WAYLAND_HEADERS_DIR ${FENNEC_SOURCE_DIR}/include/fennec/platform/linux/wayland/lib/headers)
set(WAYLAND_SOURCES_DIR ${FENNEC_SOURCE_DIR}/include/fennec/platform/linux/wayland/lib/sources)
# Search for base protocol xml
find_file(WAYLAND_PROTOCOL NAMES wayland.xml PATHS /usr/share/wayland /usr/share/wayland-protocols)
file(COPY ${WAYLAND_PROTOCOL} DESTINATION ${WAYLAND_PROTOCOLS_DIR})
# search for xdg protocols
find_file(XDG_SHELL_PROTOCOL NAMES xdg-shell.xml PATHS /usr/share/wayland-protocols/stable/xdg-shell)
file(COPY ${XDG_SHELL_PROTOCOL} DESTINATION ${WAYLAND_PROTOCOLS_DIR})
# include sub-dependencies
include("${FENNEC_SOURCE_DIR}/cmake/xkb.cmake")
fennec_check_xkb()
# generate protocols, based on SDL3
file(GLOB WAYLAND_PROTOCOLS_XML RELATIVE "${WAYLAND_PROTOCOLS_DIR}" "${WAYLAND_PROTOCOLS_DIR}/*.xml")
foreach(_XML IN LISTS WAYLAND_PROTOCOLS_XML)
get_filename_component(_FILE ${_XML} NAME_WLE)
fennec_wayland_get_header("${WAYLAND_SCANNER}" "${WAYLAND_PROTOCOLS_DIR}/${_XML}" "${_FILE}")
endforeach()
# Add sources and libraries
get_filename_component(
WAYLAND_CLIENT_LIBRARY
${WAYLAND_CLIENT_LIBRARY}
NAME
)
get_filename_component(
WAYLAND_EGL_LIBRARY
${WAYLAND_EGL_LIBRARY}
NAME
)
set(WAYLAND_CLIENT_FOUND 1)
set(WAYLAND_EGL_FOUND 1)
set(FENNEC_GRAPHICS_WANT_EGL 1)
fennec_add_sources(
# Dynamic Library Files
include/fennec/platform/linux/wayland/lib/sym.h
include/fennec/platform/linux/wayland/lib/wayland.h
include/fennec/platform/linux/wayland/lib/loader.h source/platform/linux/wayland/lib/loader.cpp
# Fennec Files
include/fennec/platform/linux/wayland/display.h source/platform/linux/wayland/display.cpp
include/fennec/platform/linux/wayland/window.h source/platform/linux/wayland/window.cpp
)
fennec_add_definitions(
FENNEC_HAS_WAYLAND=1
FENNEC_LIB_WAYLAND="${WAYLAND_CLIENT_LIBRARY}"
FENNEC_LIB_WAYLAND_EGL="${WAYLAND_EGL_LIBRARY}"
)
endif()
endmacro()

View File

@@ -1,58 +0,0 @@
# ======================================================================================================================
# 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/>.
# ======================================================================================================================
# this script finds libxkbcommon and dependencies
macro(fennec_check_xkb)
set(XKB_FOUND 0)
find_path(
XKB_INCLUDE_DIR
NAMES xkbcommon/xkbcommon.h
)
find_library(
XKB_LIBRARY
NAMES xkbcommon libxkbcommon
)
if(XKB_INCLUDE_DIR AND XKB_LIBRARY)
message(STATUS "Found XKB: ${XKB_LIBRARY}")
get_filename_component(
XKB_LIBRARY
${XKB_LIBRARY}
NAME
)
set(XKB_FOUND 1)
fennec_add_sources(
# Dynamic Library Files
include/fennec/platform/linux/xkb/lib/sym.h
include/fennec/platform/linux/xkb/lib/xkb.h
include/fennec/platform/linux/xkb/lib/loader.h source/platform/linux/xkb/lib/loader.cpp
# Fennec files
)
fennec_add_definitions(
FENNEC_HAS_XKB=1
FENNEC_LIB_XKB="${XKB_LIBRARY}"
)
endif()
endmacro()

1
external/SDL vendored Submodule

Submodule external/SDL added at dee2414ee7

View File

@@ -1,83 +0,0 @@
// =====================================================================================================================
// 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/>.
// =====================================================================================================================
#ifndef FENNEC_PLATFORM_INTERFACE_DISPLAY_H
#define FENNEC_PLATFORM_INTERFACE_DISPLAY_H
#include <fennec/langproc/strings/string.h>
#include <fennec/lang/types.h>
#include <fennec/lang/typeuuid.h>
#include <fennec/platform/interface/fwd.h>
namespace fennec
{
class display : public typed<display>
{
public:
struct pixel_format {
uint8_t depth;
uint8_t r, g, b;
};
struct config {
pixel_format format;
};
virtual bool connected() const = 0;
virtual ~display();
virtual window* create_window(window* parent) = 0;
const pixel_format& get_color_format() const {
return _config.format;
}
virtual void select_context();
virtual void* get_native_handle() = 0;
platform* get_platform() { return _platform; }
gfxcontext* get_context() { return _context; }
const string name;
protected:
platform* _platform;
gfxcontext* _context;
config _config;
template<typename DisplayT>
explicit display(platform* platform, const cstring& name, DisplayT* type)
: typed(type)
, name(name)
, _platform(platform)
, _context(nullptr)
, _config {
.format = {
.depth = 24,
.r = 8,
.g = 8,
.b = 8,
}
} {
}
};
}
#endif // FENNEC_PLATFORM_INTERFACE_DISPLAY_H

View File

@@ -22,12 +22,7 @@
namespace fennec
{
class platform; // Handles OS level functionality
class display; // Handles display protocols
class window; // Handles window surfaces of the display protocol
class inputdevice; // Handles input devices
class gfxcontext; // Handle Driver Contexts, i.e. EGL, WGL, VkWayland, etc.
class gfxsurface; // Handle surface targets for windows
}

View File

@@ -1,64 +0,0 @@
// =====================================================================================================================
// 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/>.
// =====================================================================================================================
#ifndef FENNEC_PLATFORM_INTERFACE_GFXCONTEXT_H
#define FENNEC_PLATFORM_INTERFACE_GFXCONTEXT_H
#include <fennec/langproc/strings/string.h>
#include <fennec/lang/typeuuid.h>
#include <fennec/platform/interface/fwd.h>
#include <fennec/platform/interface/window.h>
namespace fennec
{
class gfxcontext : public typed<gfxcontext> {
public:
const string name;
virtual bool connected() = 0;
virtual const cstring& get_name() = 0;
virtual int32_t get_version_major() = 0;
virtual int32_t get_version_minor() = 0;
virtual int32_t get_version() = 0;
virtual bool check_extension(const cstring& ext) = 0;
virtual void make_current(gfxsurface* surface) = 0;
virtual gfxsurface* create_surface(window* window) = 0;
virtual ~gfxcontext() = default;
display* get_display() {
return _display;
}
protected:
display* _display;
template<typename ContextT>
gfxcontext(display* display, const cstring& name, ContextT* type)
: typed(type)
, name(name)
, _display(display) {
}
};
}
#endif // FENNEC_PLATFORM_INTERFACE_GFXCONTEXT_H

View File

@@ -1,76 +0,0 @@
// =====================================================================================================================
// 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/>.
// =====================================================================================================================
///
/// \file gfxsurface.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_INTERFACE_GFXSURFACE_H
#define FENNEC_PLATFORM_INTERFACE_GFXSURFACE_H
#include <fennec/lang/types.h>
#include <fennec/lang/typeuuid.h>
#include <fennec/platform/interface/fwd.h>
#include <fennec/platform/interface/window.h>
namespace fennec
{
class gfxsurface : public typed<gfxsurface> {
public:
virtual ~gfxsurface() = default;
virtual void resize(size_t width, size_t height) {
_width = width;
_height = height;
}
gfxcontext* get_context() {
return _context;
}
window* get_window() {
return _window;
}
protected:
gfxcontext* _context;
window* _window;
size_t _width, _height;
template<typename SurfaceT>
gfxsurface(gfxcontext* ctx, window* window, SurfaceT* type)
: typed(type)
, _context(ctx)
, _window(window)
, _width(window->get_width()), _height(window->get_height()) {
}
};
}
#endif // FENNEC_PLATFORM_INTERFACE_GFXSURFACE_H

View File

@@ -76,8 +76,6 @@ public:
virtual void initialize(); // Initialize Drivers and Contexts
virtual void shutdown(); // Close Drivers and Contexts
display* get_display() { return _display; }
protected:
template<typename PlatformT>
explicit platform(const cstring& name, PlatformT* type)
@@ -88,20 +86,12 @@ protected:
globals.singleton = this;
}
virtual void load_display();
display* _display;
private:
platform(const platform&) = delete;
// Static Stuff ========================================================================================================
public:
using display_ctor = display* (*)(platform*);
using input_ctor = inputdevice* (*)(display*);
using gfxctx_ctor = gfxcontext* (*)(display*);
template<typename ctor>
struct driver {
int priority;
@@ -110,19 +100,12 @@ public:
struct global_context {
platform* singleton;
list<driver<display_ctor>> displays;
list<driver<input_ctor>> inputs;
list<driver<gfxctx_ctor>> graphics;
global_context()
: singleton(nullptr) {
}
};
static void add_driver(display_ctor ctor, int priority);
static void add_driver(input_ctor ctor, int priority);
static void add_driver(gfxctx_ctor ctor, int priority);
private:
static global_context& _get_globals();

View File

@@ -16,154 +16,120 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file window.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_INTERFACE_WINDOW_H
#define FENNEC_PLATFORM_INTERFACE_WINDOW_H
#include <fennec/containers/optional.h>
#include <fennec/lang/types.h>
#include <fennec/langproc/strings/string.h>
#include <fennec/platform/interface/fwd.h>
#include <fennec/platform/linux/wayland/display.h>
namespace fennec
{
///
/// \brief interface for handling windows
/// \details the interface makes no guarantees about the bit-depth and is completely dependent on the implementation.
class window : public typed<window> {
class window {
public:
enum class fullscreen_mode {
windowed = 0,
borderless,
fullscreen
enum flags : uint8_t {
fullscreen = 0x1 << 0,
borderless = 0x1 << 1,
resizeable = 0x1 << 2,
modal = 0x1 << 3, // Treat as modal, blocks interaction with parent windows
popup = 0x1 << 4, // Treat as a popup menu
tooltip = 0x1 << 5, // Treat as a tooltip, does not receive mouse or keyboard focus
utility = 0x1 << 6, // Treat as utility, does not show in taskbar
};
enum flags_ : uint32_t {
flags_none = 0,
flags_child = 0x1 << 0,
flags_modal = 0x1 << 1,
flags_grab_mouse = 0x1 << 2,
flags_grab_keyboard = 0x1 << 3,
flags_block_screensaver = 0x1 << 4,
enum vsync {
off = 0,
vsync = 1,
adaptive_sync = -1,
};
struct pixel_format {
uint8_t r, g, b, a;
bool floating_point;
};
struct display_mode {
pixel_format format;
float rate;
float density;
};
struct config {
string title;
uint32_t flags;
size_t width, height;
fullscreen_mode fullscreen;
uint8_t flags;
display_mode mode;
string title;
int8_t vsync;
};
virtual ~window() = default;
// Properties ==========================================================================================================
virtual bool running() = 0;
virtual void configure(const config& config) = 0;
virtual bool initialize(bool modal) = 0;
virtual bool shutdown() = 0;
bool is_fullscreen() const {
return _config.flags & fullscreen;
}
virtual bool set_title(const cstring& title) = 0;
virtual bool set_title(const string& title) = 0;
virtual bool set_width(size_t w) = 0;
virtual bool set_height(size_t h) = 0;
virtual bool resize(size_t w, size_t h) = 0;
virtual bool set_fullscreen_mode(fullscreen_mode mode) = 0;
virtual bool set_resizable(bool e) = 0;
virtual bool grab_keyboard(bool e) = 0;
virtual bool grab_mouse(bool e) = 0;
virtual bool block_screensaver(bool e) = 0;
virtual struct wl_surface* get_native_handle() = 0;
bool is_child() const {
if (not _config) return false;
return _config->flags & flags_child;
bool is_borderless() const {
return _config.flags & borderless;
}
bool is_modal() const {
if (not _config) return false;
return _config->flags & flags_modal;
return _config.flags & modal;
}
display* get_display() {
return _display;
bool is_resizeable() const {
return _config.flags & resizeable;
}
const display* get_display() const {
return _display;
const display_mode& get_mode() const {
return _config.mode;
}
const pixel_format& get_format() const {
return _config.mode.format;
}
bool is_hdr() const {
static constexpr size_t sdr = 255ull * 255ull * 255ull;
const pixel_format& fmt = _config.mode.format;
return fmt.r * fmt.g * fmt.b > sdr;
}
const config& get_config() const {
return *_config;
return _config;
}
// Modifiers ===========================================================================================================
const string& get_title() const {
static const string _null{"null"};
if (not _config) return _null;
return _config->title;
}
size_t get_width() const {
if (not _config) return false;
return _config->width;
}
size_t get_height() const {
if (not _config) return false;
return _config->height;
}
fullscreen_mode get_fullscreen_mode() const {
if (not _config) return fullscreen_mode::windowed;
return _config->fullscreen;
}
bool is_keyboard_grabbed() const {
if (not _config) return false;
return _config->flags & flags_grab_keyboard;
}
bool is_mouse_grabbed() const {
if (not _config) return false;
return _config->flags & flags_grab_mouse;
}
bool is_screensaver_blocked() const {
if (not _config) return false;
return _config->flags & flags_block_screensaver;
}
template<class DisplayT>
DisplayT* get_display() {
return static_cast<DisplayT*>(_display);
}
virtual void set_fullscreen(bool) = 0;
virtual void set_borderless(bool) = 0;
virtual void grab_mouse(bool) = 0;
virtual void grab_keyboard(bool) = 0;
virtual void set_title(const cstring&) = 0;
virtual void set_title(const string& str) = 0;
virtual void set_vsync_mode(int8_t) = 0;
protected:
template<typename TypeT>
window(display* display, window* parent, TypeT* type)
: typed(type)
, _display(display)
, _parent(parent)
, _surface(nullptr) {
window* _parent;
config _config;
window(window* parent, const config& cfg)
: _parent(parent)
, _config(cfg) {
}
display* _display;
window* _parent;
optional<config> _config;
gfxsurface* _surface;
private:
private:
};
}
#endif // FENNEC_PLATFORM_INTERFACE_WINDOW_H
#endif // FENNEC_PLATFORM_INTERFACE_WINDOW_H

View File

@@ -1,71 +0,0 @@
// =====================================================================================================================
// 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/>.
// =====================================================================================================================
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H
#include <fennec/platform/interface/display.h>
#include <fennec/platform/linux/wayland/lib/wayland.h>
namespace fennec
{
class wayland_display : public display {
public:
explicit wayland_display(platform* platform);
~wayland_display() override;
bool connected() const override;
void* get_native_handle() override { return _handle; }
window* create_window(window* parent) override;
wl_registry* get_registry() { return _registry; }
const wl_registry* get_registry() const { return _registry; }
wl_compositor* get_compositor() { return _compositor; }
const wl_compositor* get_compositor() const { return _compositor; }
// xdg_wm_base* get_shell() { return _shell; }
//const xdg_wm_base* get_shell() const { return _shell; }
wl_seat* get_seat() { return _seat; }
const wl_seat* get_seat() const { return _seat; }
wl_shm* get_shm() { return _shm; }
const wl_shm* get_shm() const { return _shm; }
private:
wl_display* _handle;
wl_registry* _registry;
wl_compositor* _compositor;
//xdg_wm_base* _shell;
wl_seat* _seat;
wl_shm* _shm;
bool _fifo;
void cleanup();
static void listen_global(void*, wl_registry*, uint32_t, const char*, uint32_t);
static void listen_global_remove(void*, wl_registry*, uint32_t);
static void listen_seat(void*, wl_seat*, uint32_t);
};
}
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H

View File

@@ -1,37 +0,0 @@
// =====================================================================================================================
// 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/>.
// =====================================================================================================================
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_DYN_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_DYN_H
#include <fennec/platform/interface/platform.h>
namespace fennec
{
namespace libwayland
{
bool load_symbols(platform* platform);
void unload_symbols(platform* platform);
}
}
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_DYN_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,526 +0,0 @@
/* Generated by wayland-scanner 1.23.1 */
/*
* Copyright © 2008-2011 Kristian Høgsberg
* Copyright © 2010-2011 Intel Corporation
* Copyright © 2012-2013 Collabora, Ltd.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface wl_buffer_interface;
extern const struct wl_interface wl_callback_interface;
extern const struct wl_interface wl_data_device_interface;
extern const struct wl_interface wl_data_offer_interface;
extern const struct wl_interface wl_data_source_interface;
extern const struct wl_interface wl_keyboard_interface;
extern const struct wl_interface wl_output_interface;
extern const struct wl_interface wl_pointer_interface;
extern const struct wl_interface wl_region_interface;
extern const struct wl_interface wl_registry_interface;
extern const struct wl_interface wl_seat_interface;
extern const struct wl_interface wl_shell_surface_interface;
extern const struct wl_interface wl_shm_pool_interface;
extern const struct wl_interface wl_subsurface_interface;
extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface wl_touch_interface;
static const struct wl_interface *wayland_types[] = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
&wl_callback_interface,
&wl_registry_interface,
&wl_surface_interface,
&wl_region_interface,
&wl_buffer_interface,
NULL,
NULL,
NULL,
NULL,
NULL,
&wl_shm_pool_interface,
NULL,
NULL,
&wl_data_source_interface,
&wl_surface_interface,
&wl_surface_interface,
NULL,
&wl_data_source_interface,
NULL,
&wl_data_offer_interface,
NULL,
&wl_surface_interface,
NULL,
NULL,
&wl_data_offer_interface,
&wl_data_offer_interface,
&wl_data_source_interface,
&wl_data_device_interface,
&wl_seat_interface,
&wl_shell_surface_interface,
&wl_surface_interface,
&wl_seat_interface,
NULL,
&wl_seat_interface,
NULL,
NULL,
&wl_surface_interface,
NULL,
NULL,
NULL,
NULL,
NULL,
&wl_output_interface,
&wl_seat_interface,
NULL,
&wl_surface_interface,
NULL,
NULL,
NULL,
&wl_output_interface,
&wl_buffer_interface,
NULL,
NULL,
&wl_callback_interface,
&wl_region_interface,
&wl_region_interface,
&wl_output_interface,
&wl_output_interface,
&wl_pointer_interface,
&wl_keyboard_interface,
&wl_touch_interface,
NULL,
&wl_surface_interface,
NULL,
NULL,
NULL,
&wl_surface_interface,
NULL,
NULL,
NULL,
&wl_surface_interface,
NULL,
&wl_surface_interface,
NULL,
NULL,
&wl_surface_interface,
NULL,
NULL,
&wl_surface_interface,
NULL,
NULL,
NULL,
&wl_subsurface_interface,
&wl_surface_interface,
&wl_surface_interface,
&wl_surface_interface,
&wl_surface_interface,
};
static const struct wl_message wl_display_requests[] = {
{ "sync", "n", wayland_types + 8 },
{ "get_registry", "n", wayland_types + 9 },
};
static const struct wl_message wl_display_events[] = {
{ "error", "ous", wayland_types + 0 },
{ "delete_id", "u", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_display_interface = {
"wl_display", 1,
2, wl_display_requests,
2, wl_display_events,
};
static const struct wl_message wl_registry_requests[] = {
{ "bind", "usun", wayland_types + 0 },
};
static const struct wl_message wl_registry_events[] = {
{ "global", "usu", wayland_types + 0 },
{ "global_remove", "u", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_registry_interface = {
"wl_registry", 1,
1, wl_registry_requests,
2, wl_registry_events,
};
static const struct wl_message wl_callback_events[] = {
{ "done", "u", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_callback_interface = {
"wl_callback", 1,
0, NULL,
1, wl_callback_events,
};
static const struct wl_message wl_compositor_requests[] = {
{ "create_surface", "n", wayland_types + 10 },
{ "create_region", "n", wayland_types + 11 },
};
WL_PRIVATE const struct wl_interface wl_compositor_interface = {
"wl_compositor", 6,
2, wl_compositor_requests,
0, NULL,
};
static const struct wl_message wl_shm_pool_requests[] = {
{ "create_buffer", "niiiiu", wayland_types + 12 },
{ "destroy", "", wayland_types + 0 },
{ "resize", "i", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_shm_pool_interface = {
"wl_shm_pool", 2,
3, wl_shm_pool_requests,
0, NULL,
};
static const struct wl_message wl_shm_requests[] = {
{ "create_pool", "nhi", wayland_types + 18 },
{ "release", "2", wayland_types + 0 },
};
static const struct wl_message wl_shm_events[] = {
{ "format", "u", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_shm_interface = {
"wl_shm", 2,
2, wl_shm_requests,
1, wl_shm_events,
};
static const struct wl_message wl_buffer_requests[] = {
{ "destroy", "", wayland_types + 0 },
};
static const struct wl_message wl_buffer_events[] = {
{ "release", "", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_buffer_interface = {
"wl_buffer", 1,
1, wl_buffer_requests,
1, wl_buffer_events,
};
static const struct wl_message wl_data_offer_requests[] = {
{ "accept", "u?s", wayland_types + 0 },
{ "receive", "sh", wayland_types + 0 },
{ "destroy", "", wayland_types + 0 },
{ "finish", "3", wayland_types + 0 },
{ "set_actions", "3uu", wayland_types + 0 },
};
static const struct wl_message wl_data_offer_events[] = {
{ "offer", "s", wayland_types + 0 },
{ "source_actions", "3u", wayland_types + 0 },
{ "action", "3u", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_data_offer_interface = {
"wl_data_offer", 3,
5, wl_data_offer_requests,
3, wl_data_offer_events,
};
static const struct wl_message wl_data_source_requests[] = {
{ "offer", "s", wayland_types + 0 },
{ "destroy", "", wayland_types + 0 },
{ "set_actions", "3u", wayland_types + 0 },
};
static const struct wl_message wl_data_source_events[] = {
{ "target", "?s", wayland_types + 0 },
{ "send", "sh", wayland_types + 0 },
{ "cancelled", "", wayland_types + 0 },
{ "dnd_drop_performed", "3", wayland_types + 0 },
{ "dnd_finished", "3", wayland_types + 0 },
{ "action", "3u", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_data_source_interface = {
"wl_data_source", 3,
3, wl_data_source_requests,
6, wl_data_source_events,
};
static const struct wl_message wl_data_device_requests[] = {
{ "start_drag", "?oo?ou", wayland_types + 21 },
{ "set_selection", "?ou", wayland_types + 25 },
{ "release", "2", wayland_types + 0 },
};
static const struct wl_message wl_data_device_events[] = {
{ "data_offer", "n", wayland_types + 27 },
{ "enter", "uoff?o", wayland_types + 28 },
{ "leave", "", wayland_types + 0 },
{ "motion", "uff", wayland_types + 0 },
{ "drop", "", wayland_types + 0 },
{ "selection", "?o", wayland_types + 33 },
};
WL_PRIVATE const struct wl_interface wl_data_device_interface = {
"wl_data_device", 3,
3, wl_data_device_requests,
6, wl_data_device_events,
};
static const struct wl_message wl_data_device_manager_requests[] = {
{ "create_data_source", "n", wayland_types + 34 },
{ "get_data_device", "no", wayland_types + 35 },
};
WL_PRIVATE const struct wl_interface wl_data_device_manager_interface = {
"wl_data_device_manager", 3,
2, wl_data_device_manager_requests,
0, NULL,
};
static const struct wl_message wl_shell_requests[] = {
{ "get_shell_surface", "no", wayland_types + 37 },
};
WL_PRIVATE const struct wl_interface wl_shell_interface = {
"wl_shell", 1,
1, wl_shell_requests,
0, NULL,
};
static const struct wl_message wl_shell_surface_requests[] = {
{ "pong", "u", wayland_types + 0 },
{ "move", "ou", wayland_types + 39 },
{ "resize", "ouu", wayland_types + 41 },
{ "set_toplevel", "", wayland_types + 0 },
{ "set_transient", "oiiu", wayland_types + 44 },
{ "set_fullscreen", "uu?o", wayland_types + 48 },
{ "set_popup", "ouoiiu", wayland_types + 51 },
{ "set_maximized", "?o", wayland_types + 57 },
{ "set_title", "s", wayland_types + 0 },
{ "set_class", "s", wayland_types + 0 },
};
static const struct wl_message wl_shell_surface_events[] = {
{ "ping", "u", wayland_types + 0 },
{ "configure", "uii", wayland_types + 0 },
{ "popup_done", "", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_shell_surface_interface = {
"wl_shell_surface", 1,
10, wl_shell_surface_requests,
3, wl_shell_surface_events,
};
static const struct wl_message wl_surface_requests[] = {
{ "destroy", "", wayland_types + 0 },
{ "attach", "?oii", wayland_types + 58 },
{ "damage", "iiii", wayland_types + 0 },
{ "frame", "n", wayland_types + 61 },
{ "set_opaque_region", "?o", wayland_types + 62 },
{ "set_input_region", "?o", wayland_types + 63 },
{ "commit", "", wayland_types + 0 },
{ "set_buffer_transform", "2i", wayland_types + 0 },
{ "set_buffer_scale", "3i", wayland_types + 0 },
{ "damage_buffer", "4iiii", wayland_types + 0 },
{ "offset", "5ii", wayland_types + 0 },
};
static const struct wl_message wl_surface_events[] = {
{ "enter", "o", wayland_types + 64 },
{ "leave", "o", wayland_types + 65 },
{ "preferred_buffer_scale", "6i", wayland_types + 0 },
{ "preferred_buffer_transform", "6u", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_surface_interface = {
"wl_surface", 6,
11, wl_surface_requests,
4, wl_surface_events,
};
static const struct wl_message wl_seat_requests[] = {
{ "get_pointer", "n", wayland_types + 66 },
{ "get_keyboard", "n", wayland_types + 67 },
{ "get_touch", "n", wayland_types + 68 },
{ "release", "5", wayland_types + 0 },
};
static const struct wl_message wl_seat_events[] = {
{ "capabilities", "u", wayland_types + 0 },
{ "name", "2s", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_seat_interface = {
"wl_seat", 9,
4, wl_seat_requests,
2, wl_seat_events,
};
static const struct wl_message wl_pointer_requests[] = {
{ "set_cursor", "u?oii", wayland_types + 69 },
{ "release", "3", wayland_types + 0 },
};
static const struct wl_message wl_pointer_events[] = {
{ "enter", "uoff", wayland_types + 73 },
{ "leave", "uo", wayland_types + 77 },
{ "motion", "uff", wayland_types + 0 },
{ "button", "uuuu", wayland_types + 0 },
{ "axis", "uuf", wayland_types + 0 },
{ "frame", "5", wayland_types + 0 },
{ "axis_source", "5u", wayland_types + 0 },
{ "axis_stop", "5uu", wayland_types + 0 },
{ "axis_discrete", "5ui", wayland_types + 0 },
{ "axis_value120", "8ui", wayland_types + 0 },
{ "axis_relative_direction", "9uu", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_pointer_interface = {
"wl_pointer", 9,
2, wl_pointer_requests,
11, wl_pointer_events,
};
static const struct wl_message wl_keyboard_requests[] = {
{ "release", "3", wayland_types + 0 },
};
static const struct wl_message wl_keyboard_events[] = {
{ "keymap", "uhu", wayland_types + 0 },
{ "enter", "uoa", wayland_types + 79 },
{ "leave", "uo", wayland_types + 82 },
{ "key", "uuuu", wayland_types + 0 },
{ "modifiers", "uuuuu", wayland_types + 0 },
{ "repeat_info", "4ii", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_keyboard_interface = {
"wl_keyboard", 9,
1, wl_keyboard_requests,
6, wl_keyboard_events,
};
static const struct wl_message wl_touch_requests[] = {
{ "release", "3", wayland_types + 0 },
};
static const struct wl_message wl_touch_events[] = {
{ "down", "uuoiff", wayland_types + 84 },
{ "up", "uui", wayland_types + 0 },
{ "motion", "uiff", wayland_types + 0 },
{ "frame", "", wayland_types + 0 },
{ "cancel", "", wayland_types + 0 },
{ "shape", "6iff", wayland_types + 0 },
{ "orientation", "6if", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_touch_interface = {
"wl_touch", 9,
1, wl_touch_requests,
7, wl_touch_events,
};
static const struct wl_message wl_output_requests[] = {
{ "release", "3", wayland_types + 0 },
};
static const struct wl_message wl_output_events[] = {
{ "geometry", "iiiiissi", wayland_types + 0 },
{ "mode", "uiii", wayland_types + 0 },
{ "done", "2", wayland_types + 0 },
{ "scale", "2i", wayland_types + 0 },
{ "name", "4s", wayland_types + 0 },
{ "description", "4s", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_output_interface = {
"wl_output", 4,
1, wl_output_requests,
6, wl_output_events,
};
static const struct wl_message wl_region_requests[] = {
{ "destroy", "", wayland_types + 0 },
{ "add", "iiii", wayland_types + 0 },
{ "subtract", "iiii", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_region_interface = {
"wl_region", 1,
3, wl_region_requests,
0, NULL,
};
static const struct wl_message wl_subcompositor_requests[] = {
{ "destroy", "", wayland_types + 0 },
{ "get_subsurface", "noo", wayland_types + 90 },
};
WL_PRIVATE const struct wl_interface wl_subcompositor_interface = {
"wl_subcompositor", 1,
2, wl_subcompositor_requests,
0, NULL,
};
static const struct wl_message wl_subsurface_requests[] = {
{ "destroy", "", wayland_types + 0 },
{ "set_position", "ii", wayland_types + 0 },
{ "place_above", "o", wayland_types + 93 },
{ "place_below", "o", wayland_types + 94 },
{ "set_sync", "", wayland_types + 0 },
{ "set_desync", "", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_subsurface_interface = {
"wl_subsurface", 1,
6, wl_subsurface_requests,
0, NULL,
};

View File

@@ -1,184 +0,0 @@
/* Generated by wayland-scanner 1.23.1 */
/*
* Copyright © 2008-2013 Kristian Høgsberg
* Copyright © 2013 Rafael Antognolli
* Copyright © 2013 Jasper St. Pierre
* Copyright © 2010-2013 Intel Corporation
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
* Copyright © 2015-2017 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface wl_output_interface;
extern const struct wl_interface wl_seat_interface;
extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface xdg_popup_interface;
extern const struct wl_interface xdg_positioner_interface;
extern const struct wl_interface xdg_surface_interface;
extern const struct wl_interface xdg_toplevel_interface;
static const struct wl_interface *xdg_shell_types[] = {
NULL,
NULL,
NULL,
NULL,
&xdg_positioner_interface,
&xdg_surface_interface,
&wl_surface_interface,
&xdg_toplevel_interface,
&xdg_popup_interface,
&xdg_surface_interface,
&xdg_positioner_interface,
&xdg_toplevel_interface,
&wl_seat_interface,
NULL,
NULL,
NULL,
&wl_seat_interface,
NULL,
&wl_seat_interface,
NULL,
NULL,
&wl_output_interface,
&wl_seat_interface,
NULL,
&xdg_positioner_interface,
NULL,
};
static const struct wl_message xdg_wm_base_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "create_positioner", "n", xdg_shell_types + 4 },
{ "get_xdg_surface", "no", xdg_shell_types + 5 },
{ "pong", "u", xdg_shell_types + 0 },
};
static const struct wl_message xdg_wm_base_events[] = {
{ "ping", "u", xdg_shell_types + 0 },
};
WL_PRIVATE const struct wl_interface xdg_wm_base_interface = {
"xdg_wm_base", 6,
4, xdg_wm_base_requests,
1, xdg_wm_base_events,
};
static const struct wl_message xdg_positioner_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "set_size", "ii", xdg_shell_types + 0 },
{ "set_anchor_rect", "iiii", xdg_shell_types + 0 },
{ "set_anchor", "u", xdg_shell_types + 0 },
{ "set_gravity", "u", xdg_shell_types + 0 },
{ "set_constraint_adjustment", "u", xdg_shell_types + 0 },
{ "set_offset", "ii", xdg_shell_types + 0 },
{ "set_reactive", "3", xdg_shell_types + 0 },
{ "set_parent_size", "3ii", xdg_shell_types + 0 },
{ "set_parent_configure", "3u", xdg_shell_types + 0 },
};
WL_PRIVATE const struct wl_interface xdg_positioner_interface = {
"xdg_positioner", 6,
10, xdg_positioner_requests,
0, NULL,
};
static const struct wl_message xdg_surface_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "get_toplevel", "n", xdg_shell_types + 7 },
{ "get_popup", "n?oo", xdg_shell_types + 8 },
{ "set_window_geometry", "iiii", xdg_shell_types + 0 },
{ "ack_configure", "u", xdg_shell_types + 0 },
};
static const struct wl_message xdg_surface_events[] = {
{ "configure", "u", xdg_shell_types + 0 },
};
WL_PRIVATE const struct wl_interface xdg_surface_interface = {
"xdg_surface", 6,
5, xdg_surface_requests,
1, xdg_surface_events,
};
static const struct wl_message xdg_toplevel_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "set_parent", "?o", xdg_shell_types + 11 },
{ "set_title", "s", xdg_shell_types + 0 },
{ "set_app_id", "s", xdg_shell_types + 0 },
{ "show_window_menu", "ouii", xdg_shell_types + 12 },
{ "move", "ou", xdg_shell_types + 16 },
{ "resize", "ouu", xdg_shell_types + 18 },
{ "set_max_size", "ii", xdg_shell_types + 0 },
{ "set_min_size", "ii", xdg_shell_types + 0 },
{ "set_maximized", "", xdg_shell_types + 0 },
{ "unset_maximized", "", xdg_shell_types + 0 },
{ "set_fullscreen", "?o", xdg_shell_types + 21 },
{ "unset_fullscreen", "", xdg_shell_types + 0 },
{ "set_minimized", "", xdg_shell_types + 0 },
};
static const struct wl_message xdg_toplevel_events[] = {
{ "configure", "iia", xdg_shell_types + 0 },
{ "close", "", xdg_shell_types + 0 },
{ "configure_bounds", "4ii", xdg_shell_types + 0 },
{ "wm_capabilities", "5a", xdg_shell_types + 0 },
};
WL_PRIVATE const struct wl_interface xdg_toplevel_interface = {
"xdg_toplevel", 6,
14, xdg_toplevel_requests,
4, xdg_toplevel_events,
};
static const struct wl_message xdg_popup_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "grab", "ou", xdg_shell_types + 22 },
{ "reposition", "3ou", xdg_shell_types + 24 },
};
static const struct wl_message xdg_popup_events[] = {
{ "configure", "iiii", xdg_shell_types + 0 },
{ "popup_done", "", xdg_shell_types + 0 },
{ "repositioned", "3u", xdg_shell_types + 0 },
};
WL_PRIVATE const struct wl_interface xdg_popup_interface = {
"xdg_popup", 6,
3, xdg_popup_requests,
3, xdg_popup_events,
};

View File

@@ -1,114 +0,0 @@
// =====================================================================================================================
// 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/lang/types.h>
#ifndef FENNEC_LIB
#define FENNEC_LIB(...)
#endif
#ifndef FENNEC_SYMBOL
#define FENNEC_SYMBOL(...)
#endif
#ifndef FENNEC_GLOBAL
#define FENNEC_GLOBAL(...)
#endif
FENNEC_LIB(WAYLAND);
FENNEC_SYMBOL(void, wl_proxy_marshal, struct wl_proxy*, uint32_t, ...);
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_flags, struct wl_proxy*, uint32_t, const struct wl_interface*, uint32_t, uint32_t, ...);
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_create, struct wl_proxy*, const struct wl_interface*);
FENNEC_SYMBOL(void, wl_proxy_destroy, struct wl_proxy*);
FENNEC_SYMBOL(int, wl_proxy_add_listener, struct wl_proxy*, void (**)(void), void*);
FENNEC_SYMBOL(void, wl_proxy_set_user_data, struct wl_proxy*, void*);
FENNEC_SYMBOL(void*, wl_proxy_get_user_data, struct wl_proxy*);
FENNEC_SYMBOL(uint32_t, wl_proxy_get_version, struct wl_proxy*);
FENNEC_SYMBOL(uint32_t, wl_proxy_get_id, struct wl_proxy*);
FENNEC_SYMBOL(const char*, wl_proxy_get_class, struct wl_proxy*);
FENNEC_SYMBOL(void, wl_proxy_set_queue, struct wl_proxy*, struct wl_event_queue*);
FENNEC_SYMBOL(void*, wl_proxy_create_wrapper, void*);
FENNEC_SYMBOL(void, wl_proxy_wrapper_destroy, void*);
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_constructor, struct wl_proxy*, uint32_t, const struct wl_interface*, ...);
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_constructor_versioned, struct wl_proxy*, uint32_t, const struct wl_interface*, uint32_t, ...);
FENNEC_SYMBOL(void, wl_proxy_set_tag, struct wl_proxy*, const char* const*);
FENNEC_SYMBOL(const char* const*, wl_proxy_get_tag, struct wl_proxy*);
FENNEC_SYMBOL(struct wl_display*, wl_display_connect, const char*);
FENNEC_SYMBOL(struct wl_display*, wl_display_connect_to_fd, int);
FENNEC_SYMBOL(void, wl_display_disconnect, struct wl_display*);
FENNEC_SYMBOL(int, wl_display_get_fd, struct wl_display*);
FENNEC_SYMBOL(int, wl_display_dispatch, struct wl_display*);
FENNEC_SYMBOL(int, wl_display_dispatch_queue, struct wl_display*, struct wl_event_queue*);
FENNEC_SYMBOL(int, wl_display_dispatch_queue_pending, struct wl_display*, struct wl_event_queue*);
FENNEC_SYMBOL(int, wl_display_dispatch_pending, struct wl_display*);
FENNEC_SYMBOL(int, wl_display_prepare_read, struct wl_display*);
FENNEC_SYMBOL(int, wl_display_prepare_read_queue, struct wl_display*, struct wl_event_queue*);
FENNEC_SYMBOL(int, wl_display_read_events, struct wl_display*);
FENNEC_SYMBOL(void, wl_display_cancel_read, struct wl_display*);
FENNEC_SYMBOL(int, wl_display_get_error, struct wl_display*);
FENNEC_SYMBOL(int, wl_display_flush, struct wl_display*);
FENNEC_SYMBOL(int, wl_display_roundtrip, struct wl_display*);
FENNEC_SYMBOL(struct wl_event_queue*, wl_display_create_queue, struct wl_display*);
FENNEC_SYMBOL(void, wl_event_queue_destroy, struct wl_event_queue*);
FENNEC_SYMBOL(void, wl_log_set_handler_client, wl_log_func_t);
FENNEC_SYMBOL(void, wl_list_init, struct wl_list*);
FENNEC_SYMBOL(void, wl_list_insert, struct wl_list*, struct wl_list*) ;
FENNEC_SYMBOL(void, wl_list_remove, struct wl_list*);
FENNEC_SYMBOL(int, wl_list_length, const struct wl_list*);
FENNEC_SYMBOL(int, wl_list_empty, const struct wl_list*);
FENNEC_SYMBOL(void, wl_list_insert_list, struct wl_list*, struct wl_list*);
FENNEC_GLOBAL(const struct wl_interface, wl_display_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_registry_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_callback_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_compositor_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_shm_pool_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_shm_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_buffer_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_data_offer_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_data_source_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_data_device_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_data_device_manager_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_shell_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_shell_surface_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_surface_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_seat_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_pointer_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_keyboard_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_touch_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_output_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_region_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_subcompositor_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_subsurface_interface);
FENNEC_LIB(WAYLAND_EGL);
FENNEC_SYMBOL(struct wl_egl_window*, wl_egl_window_create, struct wl_surface *surface, int width, int height);
FENNEC_SYMBOL(void, wl_egl_window_destroy, struct wl_egl_window *egl_window);
FENNEC_SYMBOL(void, wl_egl_window_resize, struct wl_egl_window *egl_window, int width, int height, int dx, int dy);
FENNEC_SYMBOL(void, wl_egl_window_get_attached_size, struct wl_egl_window *egl_window, int *width, int *height);
#undef FENNEC_LIB
#undef FENNEC_SYMBOL
#undef FENNEC_GLOBAL

View File

@@ -1,98 +0,0 @@
// =====================================================================================================================
// 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/>.
// =====================================================================================================================
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_CLIENT_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_CLIENT_H
#include <wayland-client-core.h>
#define FENNEC_LIB(name) extern "C" bool FENNEC_HAS_LIB_##name;
#define FENNEC_SYMBOL(ret, fn, ...) using WAYLAND_sym_##fn = ret(*)(__VA_ARGS__); \
extern "C" WAYLAND_sym_##fn WAYLAND_##fn;
#define FENNEC_GLOBAL(type, name) extern "C" type* WAYLAND_##name;
#include <fennec/platform/linux/wayland/lib/sym.h>
#define wl_proxy_marshal WAYLAND_wl_proxy_marshal
#define wl_proxy_marshal_flags WAYLAND_wl_proxy_marshal_flags
#define wl_proxy_create WAYLAND_wl_proxy_create
#define wl_proxy_destroy WAYLAND_wl_proxy_destroy
#define wl_proxy_add_listener WAYLAND_wl_proxy_add_listener
#define wl_proxy_set_user_data WAYLAND_wl_proxy_set_user_data
#define wl_proxy_get_user_data WAYLAND_wl_proxy_get_user_data
#define wl_proxy_get_version WAYLAND_wl_proxy_get_version
#define wl_proxy_get_id WAYLAND_wl_proxy_get_id
#define wl_proxy_get_class WAYLAND_wl_proxy_get_class
#define wl_proxy_set_queue WAYLAND_wl_proxy_set_queue
#define wl_proxy_create_wrapper WAYLAND_wl_proxy_create_wrapper
#define wl_proxy_wrapper_destroy WAYLAND_wl_proxy_wrapper_destroy
#define wl_proxy_marshal_constructor WAYLAND_wl_proxy_marshal_constructor
#define wl_proxy_marshal_constructor_versioned WAYLAND_wl_proxy_marshal_constructor_versioned
#define wl_proxy_set_tag WAYLAND_wl_proxy_set_tag
#define wl_proxy_get_tag WAYLAND_wl_proxy_get_tag
#define wl_event_queue_destroy WAYLAND_wl_event_queue_destroy
#define wl_log_set_handler_client WAYLAND_wl_log_set_handler_client
#define wl_list_init WAYLAND_wl_list_init
#define wl_list_insert WAYLAND_wl_list_insert
#define wl_list_remove WAYLAND_wl_list_remove
#define wl_list_length WAYLAND_wl_list_length
#define wl_list_empty WAYLAND_wl_list_empty
#define wl_list_insert_list WAYLAND_wl_list_insert_list
#define wl_display_connect WAYLAND_wl_display_connect
#define wl_display_connect_to_fd WAYLAND_wl_display_connect_to_fd
#define wl_display_reconnect WAYLAND_wl_display_reconnect
#define wl_display_disconnect WAYLAND_wl_display_disconnect
#define wl_display_get_fd WAYLAND_wl_display_get_fd
#define wl_display_dispatch WAYLAND_wl_display_dispatch
#define wl_display_dispatch_queue WAYLAND_wl_display_dispatch_queue
#define wl_display_dispatch_queue_pending WAYLAND_wl_display_dispatch_queue_pending
#define wl_display_dispatch_pending WAYLAND_wl_display_dispatch_pending
#define wl_display_prepare_read WAYLAND_wl_display_prepare_read
#define wl_display_prepare_read_queue WAYLAND_wl_display_prepare_read_queue
#define wl_display_read_events WAYLAND_wl_display_read_events
#define wl_display_cancel_read WAYLAND_wl_display_cancel_read
#define wl_display_get_error WAYLAND_wl_display_get_error
#define wl_display_flush WAYLAND_wl_display_flush
#define wl_display_roundtrip WAYLAND_wl_display_roundtrip
#define wl_display_create_queue WAYLAND_wl_display_create_queue
#define wl_seat_interface *WAYLAND_wl_seat_interface
#define wl_surface_interface *WAYLAND_wl_surface_interface
#define wl_shm_pool_interface *WAYLAND_wl_shm_pool_interface
#define wl_buffer_interface *WAYLAND_wl_buffer_interface
#define wl_registry_interface *WAYLAND_wl_registry_interface
#define wl_region_interface *WAYLAND_wl_region_interface
#define wl_pointer_interface *WAYLAND_wl_pointer_interface
#define wl_keyboard_interface *WAYLAND_wl_keyboard_interface
#define wl_compositor_interface *WAYLAND_wl_compositor_interface
#define wl_output_interface *WAYLAND_wl_output_interface
#define wl_shm_interface *WAYLAND_wl_shm_interface
#define wl_data_device_interface *WAYLAND_wl_data_device_interface
#define wl_data_offer_interface *WAYLAND_wl_data_offer_interface
#define wl_data_source_interface *WAYLAND_wl_data_source_interface
#define wl_data_device_manager_interface *WAYLAND_wl_data_device_manager_interface
#define wl_egl_window_create WAYLAND_wl_egl_window_create
#define wl_egl_window_destroy WAYLAND_wl_egl_window_destroy
#define wl_egl_window_resize WAYLAND_wl_egl_window_resize
#define wl_egl_window_get_attached_size WAYLAND_wl_egl_window_get_attached_size
#include <fennec/platform/linux/wayland/lib/headers/wayland-client-protocols.h>
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_CLIENT_H

View File

@@ -1,83 +0,0 @@
// =====================================================================================================================
// 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/>.
// =====================================================================================================================
///
/// \file window.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H
#include <fennec/platform/interface/window.h>
#include <fennec/platform/linux/wayland/display.h>
namespace fennec
{
class wayland_window : public window {
public:
bool running() override;
void configure(const config& config) override;
bool initialize(bool modal) override;
bool shutdown() override;
bool set_title(const cstring& title) override;
bool set_title(const string& title) override;
bool set_width(size_t w) override;
bool set_height(size_t h) override;
bool resize(size_t w, size_t h) override;
bool set_resizable(bool e) override;
bool set_fullscreen_mode(fullscreen_mode mode) override;
bool grab_keyboard(bool e) override;
bool grab_mouse(bool e) override;
bool block_screensaver(bool e) override;
wayland_window(wayland_display* display, wayland_window* parent);
~wayland_window() override;
struct wl_surface* get_native_handle() override {
return _handle;
}
private:
wl_surface* _handle;
wl_shell_surface* _shell;
size_t _nfs_width, _nfs_height;
static void listen_ping(void*, wl_shell_surface*, uint32_t);
static void listen_configure(void*, wl_shell_surface*, uint32_t, int32_t, int32_t);
static void listen_popup_done(void*, wl_shell_surface*);
};
}
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H

View File

@@ -1,37 +0,0 @@
// =====================================================================================================================
// 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/>.
// =====================================================================================================================
#ifndef FENNEC_PLATFORM_LINUX_XKB_DYN_H
#define FENNEC_PLATFORM_LINUX_XKB_DYN_H
#include <fennec/platform/interface/platform.h>
namespace fennec
{
namespace libxkbcommon
{
bool load_symbols(platform* platform);
void unload_symbols(platform* platform);
}
}
#endif // FENNEC_PLATFORM_LINUX_XKB_DYN_H

View File

@@ -1,144 +0,0 @@
// =====================================================================================================================
// 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/>.
// =====================================================================================================================
/*
* Copyright © 2009-2012 Daniel Stone
* Copyright © 2012 Intel Corporation
* Copyright © 2012 Ran Benita
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Author: Daniel Stone <daniel@fooishbar.org>
*/
#include <stdio.h>
#ifndef FENNEC_LIB
#define FENNEC_LIB(...)
#endif
#ifndef FENNEC_SYMBOL
#define FENNEC_SYMBOL(...)
#endif
#ifndef FENNEC_GLOBAL
#define FENNEC_GLOBAL(...)
#endif
FENNEC_LIB(XKB);
FENNEC_SYMBOL(int, xkb_keysym_get_name, xkb_keysym_t, char*, size_t);
FENNEC_SYMBOL(xkb_keysym_t, xkb_keysym_from_name, const char*, enum xkb_keysym_flags);
FENNEC_SYMBOL(int, xkb_keysym_to_utf8, xkb_keysym_t, char*, size_t);
FENNEC_SYMBOL(uint32_t, xkb_keysym_to_utf32, xkb_keysym_t);
FENNEC_SYMBOL(xkb_keysym_t, xkb_utf32_to_keysym, uint32_t);
FENNEC_SYMBOL(xkb_keysym_t, xkb_keysym_to_upper, xkb_keysym_t);
FENNEC_SYMBOL(xkb_keysym_t, xkb_keysym_to_lower, xkb_keysym_t);
FENNEC_SYMBOL(struct xkb_context*, xkb_context_new, enum xkb_context_flags);
FENNEC_SYMBOL(struct xkb_context*, xkb_context_ref, struct xkb_context*);
FENNEC_SYMBOL(void, xkb_context_unref, struct xkb_context*);
FENNEC_SYMBOL(void, xkb_context_set_user_data, struct xkb_context*, void*);
FENNEC_SYMBOL(void*, xkb_context_get_user_data, struct xkb_context*);
FENNEC_SYMBOL(int, xkb_context_include_path_append, struct xkb_context*, const char*);
FENNEC_SYMBOL(int, xkb_context_include_path_append_default, struct xkb_context*);
FENNEC_SYMBOL(int, xkb_context_include_path_reset_defaults, struct xkb_context*);
FENNEC_SYMBOL(void, xkb_context_include_path_clear, struct xkb_context*);
FENNEC_SYMBOL(unsigned int, xkb_context_num_include_paths, struct xkb_context*);
FENNEC_SYMBOL(const char*, xkb_context_include_path_get, struct xkb_context*, unsigned int);
FENNEC_SYMBOL(void, xkb_context_set_log_level, struct xkb_context*, enum xkb_log_level);
FENNEC_SYMBOL(enum xkb_log_level, xkb_context_get_log_level, struct xkb_context*);
FENNEC_SYMBOL(void, xkb_context_set_log_verbosity, struct xkb_context*, int);
FENNEC_SYMBOL(int, xkb_context_get_log_verbosity, struct xkb_context*);
FENNEC_SYMBOL(void, xkb_context_set_log_fn, struct xkb_context*, void (*)(struct xkb_context*, enum xkb_log_level, const char*, va_list));
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_new_from_names, struct xkb_context*, const struct xkb_rule_names*, enum xkb_keymap_compile_flags);
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_new_from_file, struct xkb_context*, FILE*, enum xkb_keymap_format, enum xkb_keymap_compile_flags);
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_new_from_string, struct xkb_context*, const char*, enum xkb_keymap_format, enum xkb_keymap_compile_flags);
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_new_from_buffer, struct xkb_context*, const char*, size_t, enum xkb_keymap_format, enum xkb_keymap_compile_flags);
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_ref, struct xkb_keymap*);
FENNEC_SYMBOL(void, xkb_keymap_unref, struct xkb_keymap*);
FENNEC_SYMBOL(char*, xkb_keymap_get_as_string, struct xkb_keymap*, enum xkb_keymap_format);
FENNEC_SYMBOL(xkb_keycode_t, xkb_keymap_min_keycode, struct xkb_keymap*);
FENNEC_SYMBOL(xkb_keycode_t, xkb_keymap_max_keycode, struct xkb_keymap*);
FENNEC_SYMBOL(void, xkb_keymap_key_for_each, struct xkb_keymap*, xkb_keymap_key_iter_t, void*);
FENNEC_SYMBOL(const char*, xkb_keymap_key_get_name, struct xkb_keymap*, xkb_keycode_t);
FENNEC_SYMBOL(xkb_keycode_t, xkb_keymap_key_by_name, struct xkb_keymap*, const char*);
FENNEC_SYMBOL(xkb_mod_index_t, xkb_keymap_num_mods, struct xkb_keymap*);
FENNEC_SYMBOL(const char*, xkb_keymap_mod_get_name, struct xkb_keymap*, xkb_mod_index_t);
FENNEC_SYMBOL(xkb_mod_index_t, xkb_keymap_mod_get_index, struct xkb_keymap*, const char*);
FENNEC_SYMBOL(xkb_layout_index_t, xkb_keymap_num_layouts, struct xkb_keymap*);
FENNEC_SYMBOL(const char*, xkb_keymap_layout_get_name, struct xkb_keymap*, xkb_layout_index_t);
FENNEC_SYMBOL(xkb_layout_index_t, xkb_keymap_layout_get_index, struct xkb_keymap*, const char*);
FENNEC_SYMBOL(xkb_led_index_t, xkb_keymap_num_leds, struct xkb_keymap*);
FENNEC_SYMBOL(const char*, xkb_keymap_led_get_name, struct xkb_keymap*, xkb_led_index_t);
FENNEC_SYMBOL(xkb_led_index_t, xkb_keymap_led_get_index, struct xkb_keymap*, const char*);
FENNEC_SYMBOL(xkb_layout_index_t, xkb_keymap_num_layouts_for_key, struct xkb_keymap*, xkb_keycode_t);
FENNEC_SYMBOL(xkb_level_index_t, xkb_keymap_num_levels_for_key, struct xkb_keymap*, xkb_keycode_t, xkb_layout_index_t);
FENNEC_SYMBOL(size_t, xkb_keymap_key_get_mods_for_level, struct xkb_keymap*, xkb_keycode_t, xkb_layout_index_t, xkb_level_index_t, xkb_mod_mask_t*, size_t);
FENNEC_SYMBOL(int, xkb_keymap_key_get_syms_by_level, struct xkb_keymap*, xkb_keycode_t, xkb_layout_index_t, xkb_level_index_t, const xkb_keysym_t**);
FENNEC_SYMBOL(int, xkb_keymap_key_repeats, struct xkb_keymap*, xkb_keycode_t);
FENNEC_SYMBOL(struct xkb_state*, xkb_state_new, struct xkb_keymap*);
FENNEC_SYMBOL(struct xkb_state*, xkb_state_ref, struct xkb_state*);
FENNEC_SYMBOL(void, xkb_state_unref, struct xkb_state*);
FENNEC_SYMBOL(struct xkb_keymap*, xkb_state_get_keymap, struct xkb_state*);
FENNEC_SYMBOL(enum xkb_state_component, xkb_state_update_key, struct xkb_state*, xkb_keycode_t, enum xkb_key_direction);
FENNEC_SYMBOL(enum xkb_state_component, xkb_state_update_mask, struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t);
FENNEC_SYMBOL(int, xkb_state_key_get_syms, struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**);
FENNEC_SYMBOL(int, xkb_state_key_get_utf8, struct xkb_state*, xkb_keycode_t, char*, size_t);
FENNEC_SYMBOL(uint32_t, xkb_state_key_get_utf32, struct xkb_state*, xkb_keycode_t);
FENNEC_SYMBOL(xkb_keysym_t, xkb_state_key_get_one_sym, struct xkb_state*, xkb_keycode_t);
FENNEC_SYMBOL(xkb_layout_index_t, xkb_state_key_get_layout, struct xkb_state*, xkb_keycode_t);
FENNEC_SYMBOL(xkb_level_index_t, xkb_state_key_get_level, struct xkb_state*, xkb_keycode_t, xkb_layout_index_t);
FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_serialize_mods, struct xkb_state*, enum xkb_state_component);
FENNEC_SYMBOL(xkb_layout_index_t, xkb_state_serialize_layout, struct xkb_state*, enum xkb_state_component);
FENNEC_SYMBOL(int, xkb_state_mod_name_is_active, struct xkb_state*, const char*, enum xkb_state_component);
FENNEC_SYMBOL(int, xkb_state_mod_names_are_active, struct xkb_state*, enum xkb_state_component, enum xkb_state_match, ...);
FENNEC_SYMBOL(int, xkb_state_mod_index_is_active, struct xkb_state*, xkb_mod_index_t, enum xkb_state_component);
FENNEC_SYMBOL(int, xkb_state_mod_indices_are_active, struct xkb_state*, enum xkb_state_component, enum xkb_state_match, ...);
FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_key_get_consumed_mods2, struct xkb_state*, xkb_keycode_t, enum xkb_consumed_mode);
FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_key_get_consumed_mods, struct xkb_state*, xkb_keycode_t);
FENNEC_SYMBOL(int, xkb_state_mod_index_is_consumed2, struct xkb_state*, xkb_keycode_t, xkb_mod_index_t, enum xkb_consumed_mode);
FENNEC_SYMBOL(int, xkb_state_mod_index_is_consumed, struct xkb_state*, xkb_keycode_t, xkb_mod_index_t);
FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_mod_mask_remove_consumed, struct xkb_state*, xkb_keycode_t, xkb_mod_mask_t);
FENNEC_SYMBOL(int, xkb_state_layout_name_is_active, struct xkb_state*, const char*, enum xkb_state_component);
FENNEC_SYMBOL(int, xkb_state_layout_index_is_active, struct xkb_state*, xkb_layout_index_t, enum xkb_state_component);
FENNEC_SYMBOL(int, xkb_state_led_name_is_active, struct xkb_state*, const char*);
FENNEC_SYMBOL(int, xkb_state_led_index_is_active, struct xkb_state*, xkb_led_index_t);
#undef FENNEC_LIB
#undef FENNEC_SYMBOL
#undef FENNEC_GLOBAL

View File

@@ -1,110 +0,0 @@
// =====================================================================================================================
// 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/>.
// =====================================================================================================================
#ifndef FENNEC_PLATFORM_LINUX_XKB_LIB_XKB_H
#define FENNEC_PLATFORM_LINUX_XKB_LIB_XKB_H
#include <xkbcommon/xkbcommon.h>
#define FENNEC_LIB(name) extern bool FENNEC_HAS_LIB_##name;
#define FENNEC_SYMBOL(ret, fn, ...) using XKB_sym_##fn = ret(*)(__VA_ARGS__); \
extern XKB_sym_##fn XKB_##fn;
#define FENNEC_GLOBAL(type, name) extern type* XKB_##name;
#include <fennec/platform/linux/xkb/lib/sym.h>
#define xkb_keysym_get_name XKB_xkb_keysym_get_name
#define xkb_keysym_from_name XKB_xkb_keysym_from_name
#define xkb_keysym_to_utf8 XKB_xkb_keysym_to_utf8
#define xkb_keysym_to_utf32 XKB_xkb_keysym_to_utf32
#define xkb_utf32_to_keysym XKB_xkb_utf32_to_keysym
#define xkb_keysym_to_upper XKB_xkb_keysym_to_upper
#define xkb_keysym_to_lower XKB_xkb_keysym_to_lower
#define xkb_context_new XKB_xkb_context_new
#define xkb_context_ref XKB_xkb_context_ref
#define xkb_context_unref XKB_xkb_context_unref
#define xkb_context_set_user_data XKB_xkb_context_set_user_data
#define xkb_context_get_user_data XKB_xkb_context_get_user_data
#define xkb_context_include_path_append XKB_xkb_context_include_path_append
#define xkb_context_include_path_append_default XKB_xkb_context_include_path_append_default
#define xkb_context_include_path_reset_defaults XKB_xkb_context_include_path_reset_defaults
#define xkb_context_include_path_clear XKB_xkb_context_include_path_clear
#define xkb_context_num_include_paths XKB_xkb_context_num_include_paths
#define xkb_context_include_path_get XKB_xkb_context_include_path_get
#define xkb_context_set_log_level XKB_xkb_context_set_log_level
#define xkb_context_get_log_level XKB_xkb_context_get_log_level
#define xkb_context_set_log_verbosity XKB_xkb_context_set_log_verbosity
#define xkb_context_get_log_verbosity XKB_xkb_context_get_log_verbosity
#define xkb_context_set_log_fn XKB_xkb_context_set_log_fn
#define xkb_keymap_new_from_names XKB_xkb_keymap_new_from_names
#define xkb_keymap_new_from_file XKB_xkb_keymap_new_from_file
#define xkb_keymap_new_from_string XKB_xkb_keymap_new_from_string
#define xkb_keymap_new_from_buffer XKB_xkb_keymap_new_from_buffer
#define xkb_keymap_ref XKB_xkb_keymap_ref
#define xkb_keymap_unref XKB_xkb_keymap_unref
#define xkb_keymap_get_as_string XKB_xkb_keymap_get_as_string
#define xkb_keymap_min_keycode XKB_xkb_keymap_min_keycode
#define xkb_keymap_max_keycode XKB_xkb_keymap_max_keycode
#define xkb_keymap_key_for_each XKB_xkb_keymap_key_for_each
#define xkb_keymap_key_get_name XKB_xkb_keymap_key_get_name
#define xkb_keymap_key_by_name XKB_xkb_keymap_key_by_name
#define xkb_keymap_num_mods XKB_xkb_keymap_num_mods
#define xkb_keymap_mod_get_name XKB_xkb_keymap_mod_get_name
#define xkb_keymap_mod_get_index XKB_xkb_keymap_mod_get_index
#define xkb_keymap_num_layouts XKB_xkb_keymap_num_layouts
#define xkb_keymap_layout_get_name XKB_xkb_keymap_layout_get_name
#define xkb_keymap_layout_get_index XKB_xkb_keymap_layout_get_index
#define xkb_keymap_num_leds XKB_xkb_keymap_num_leds
#define xkb_keymap_led_get_name XKB_xkb_keymap_led_get_name
#define xkb_keymap_led_get_index XKB_xkb_keymap_led_get_index
#define xkb_keymap_num_layouts_for_key XKB_xkb_keymap_num_layouts_for_key
#define xkb_keymap_num_levels_for_key XKB_xkb_keymap_num_levels_for_key
#define xkb_keymap_key_get_mods_for_level XKB_xkb_keymap_key_get_mods_for_level
#define xkb_keymap_key_get_syms_by_level XKB_xkb_keymap_key_get_syms_by_level
#define xkb_keymap_key_repeats XKB_xkb_keymap_key_repeats
#define xkb_state_new XKB_xkb_state_new
#define xkb_state_ref XKB_xkb_state_ref
#define xkb_state_unref XKB_xkb_state_unref
#define xkb_state_get_keymap XKB_xkb_state_get_keymap
#define xkb_state_update_key XKB_xkb_state_update_key
#define xkb_state_update_mask XKB_xkb_state_update_mask
#define xkb_state_key_get_syms XKB_xkb_state_key_get_syms
#define xkb_state_key_get_utf8 XKB_xkb_state_key_get_utf8
#define xkb_state_key_get_utf32 XKB_xkb_state_key_get_utf32
#define xkb_state_key_get_one_sym XKB_xkb_state_key_get_one_sym
#define xkb_state_key_get_layout XKB_xkb_state_key_get_layout
#define xkb_state_key_get_level XKB_xkb_state_key_get_level
#define xkb_state_serialize_mods XKB_xkb_state_serialize_mods
#define xkb_state_serialize_layout XKB_xkb_state_serialize_layout
#define xkb_state_mod_name_is_active XKB_xkb_state_mod_name_is_active
#define xkb_state_mod_names_are_active XKB_xkb_state_mod_names_are_active
#define xkb_state_mod_index_is_active XKB_xkb_state_mod_index_is_active
#define xkb_state_mod_indices_are_active XKB_xkb_state_mod_indices_are_active
#define xkb_state_key_get_consumed_mods2 XKB_xkb_state_key_get_consumed_mods2
#define xkb_state_key_get_consumed_mods XKB_xkb_state_key_get_consumed_mods
#define xkb_state_mod_index_is_consumed2 XKB_xkb_state_mod_index_is_consumed2
#define xkb_state_mod_index_is_consumed XKB_xkb_state_mod_index_is_consumed
#define xkb_state_mod_mask_remove_consumed XKB_xkb_state_mod_mask_remove_consumed
#define xkb_state_layout_name_is_active XKB_xkb_state_layout_name_is_active
#define xkb_state_layout_index_is_active XKB_xkb_state_layout_index_is_active
#define xkb_state_led_name_is_active XKB_xkb_state_led_name_is_active
#define xkb_state_led_index_is_active XKB_xkb_state_led_index_is_active
#endif // FENNEC_PLATFORM_LINUX_XKB_LIB_XKB_H

View File

@@ -1,70 +0,0 @@
// =====================================================================================================================
// 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/>.
// =====================================================================================================================
#ifndef FENNEC_PLATFORM_OPENGL_EGL_CONTEXT_H
#define FENNEC_PLATFORM_OPENGL_EGL_CONTEXT_H
#include <EGL/egl.h>
#include <fennec/platform/interface/gfxcontext.h>
#include <fennec/platform/opengl/egl/fwd.h>
namespace fennec
{
class eglcontext : public gfxcontext {
public:
eglcontext(display* display);
~eglcontext() override;
bool connected() override;
int32_t get_version_major() override { return _eglvmajor; }
int32_t get_version_minor() override { return _eglvminor; }
int32_t get_version() override { return _eglctype; }
const cstring& get_name() override;
bool check_extension(const cstring& ext) override;
gfxsurface* create_surface(window* window) override;
void make_current(gfxsurface* surface) override;
EGLDisplay get_egl_display() {
return _egldisplay;
}
EGLDisplay get_egl_context() {
return _eglcontext;
}
EGLDisplay get_egl_config() {
return _eglconfig;
}
private:
EGLDisplay _egldisplay;
EGLContext _eglcontext;
EGLConfig _eglconfig;
EGLint _eglvmajor, _eglvminor, _eglctype;
cstring _extensions;
void cleanup();
};
}
#endif // FENNEC_PLATFORM_OPENGL_EGL_CONTEXT_H

View File

@@ -1,60 +0,0 @@
// =====================================================================================================================
// 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/>.
// =====================================================================================================================
///
/// \file surface.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H
#define FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H
#include <fennec/platform/interface/gfxsurface.h>
#include <fennec/platform/linux/wayland/window.h>
#include <fennec/platform/opengl/egl/context.h>
namespace fennec
{
class eglsurface : public gfxsurface {
public:
~eglsurface() override;
void resize(size_t width, size_t height) override;
eglsurface(eglcontext* context, window* window);
EGLSurface get_egl_surface() {
return _surface;
}
private:
void* _handle;
EGLSurface _surface;
};
}
#endif // FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H

View File

@@ -17,7 +17,7 @@
// =====================================================================================================================
///
/// \file fwd.h
/// \file sdlwindow.h
/// \brief
///
///
@@ -28,15 +28,14 @@
///
///
#ifndef FENNEC_PLATFORM_OPENGL_EGL_FWD_H
#define FENNEC_PLATFORM_OPENGL_EGL_FWD_H
#ifndef FENNEC_PLATFORM_SDL_SDLWINDOW_H
#define FENNEC_PLATFORM_SDL_SDLWINDOW_H
namespace fennec
{
class eglcontext;
class eglsurface;
}
#endif // FENNEC_PLATFORM_OPENGL_EGL_FWD_H
#endif // FENNEC_PLATFORM_SDL_SDLWINDOW_H

View File

@@ -20,6 +20,14 @@ to supporting various platforms. Platforms may be defined as any Hardware, OS, o
Drivers that must be initialized for the engine context.
## Changes
&ensp; For the foreseeable future, I will be switching to SDL for window management.
SDL was chosen over GLFW due to GLFW's lack of support for Android and iOS. A custom
implementation is still something I would like to do, but is currently out of scope for
where I would like to focus my energy. As soon as SDL becomes
## Implementation
Platform Support will be implemented in the following order:

View File

@@ -1,42 +0,0 @@
// =====================================================================================================================
// 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/display.h>
#include <fennec/platform/interface/gfxcontext.h>
#include <fennec/platform/interface/platform.h>
namespace fennec
{
display::~display() {
delete _context;
}
void display::select_context() {
if (_context != nullptr) return;
const platform::global_context& globals = platform::get_globals();
for (const auto& ctx : globals.graphics) {
_context = ctx.constructor(this);
if (_context) {
return;
}
}
}
}

View File

@@ -16,7 +16,6 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/platform/interface/display.h>
#include <fennec/platform/interface/platform.h>
namespace fennec
@@ -37,37 +36,9 @@ static constexpr void insert_driver(list<platform::driver<CtorT>>& drvrs, CtorT
}
void platform::initialize() {
load_display();
_display->select_context();
}
void platform::shutdown() {
delete _display;
}
void platform::load_display() {
auto& globals = _get_globals();
for (auto it : globals.displays) {
_display = it.constructor(this);
if (_display != nullptr) {
return;
}
}
}
void platform::add_driver(display_ctor ctor, int priority) {
auto& globals = _get_globals();
insert_driver(globals.displays, ctor, priority);
}
void platform::add_driver(input_ctor ctor, int priority) {
auto& globals = _get_globals();
insert_driver(globals.inputs, ctor, priority);
}
void platform::add_driver(gfxctx_ctor ctor, int priority) {
auto& globals = _get_globals();
insert_driver(globals.graphics, ctor, priority);
}
platform::global_context& platform::_get_globals() {

View File

@@ -29,11 +29,9 @@ STATIC_CONSTRUCTOR(_init_linux) {
}
void linux_platform::initialize() {
platform::initialize();
}
void linux_platform::shutdown() {
platform::shutdown();
}
}

View File

@@ -1,140 +0,0 @@
// =====================================================================================================================
// 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/display.h>
#include <fennec/platform/linux/wayland/lib/loader.h>
#include <fennec/platform/linux/wayland/lib/wayland.h>
#include <fennec/lang/startup.h>
#include <fennec/platform/linux/wayland/window.h>
#include <fennec/platform/linux/wayland/lib/headers/wayland-client-protocols.h>
namespace fennec
{
static display* _create_wayland_display(platform* platform) {
wayland_display* display = new wayland_display(platform);
if (not display->connected()) {
delete display, display = nullptr;
}
return display;
}
STATIC_CONSTRUCTOR(_wayland_init) {
platform::add_driver(_create_wayland_display, 1);
}
wayland_display::wayland_display(platform* platform)
: display(platform, "wayland", this)
, _handle(nullptr)
, _registry(nullptr)
, _compositor(nullptr)
, _seat(nullptr)
, _shm(nullptr)
, _fifo(false) {
static constexpr wl_registry_listener listener = {
listen_global, listen_global_remove
};
// Load libwayland.so
libwayland::load_symbols(_platform);
// Get handles
_handle = wl_display_connect(nullptr);
if (not _handle) {
cleanup();
return;
}
// Get the wayland registry
_registry = wl_display_get_registry(_handle);
if (not _registry) {
cleanup();
return;
}
// Add listener for interfaces
wl_registry_add_listener(_registry, &listener, this);
wl_display_roundtrip(_handle);
// Check for fifo v1, wayland's builtin fifo only allows one frame to be in flight at a time
if (not _fifo) {
assert(_fifo, "Compositor does not support fifo-v1 protocol, falling back to other display protocols.");
cleanup();
}
}
wayland_display::~wayland_display() {
if (_handle) {
cleanup();
}
}
bool wayland_display::connected() const {
return _handle != nullptr;
}
window* wayland_display::create_window(window* parent) {
return new wayland_window(this, static_cast<wayland_window*>(parent));
}
void wayland_display::cleanup() {
// Cleanup members
if (_compositor) wl_compositor_destroy(_compositor);
if (_registry) wl_registry_destroy(_registry);
if (_handle) {
wl_display_flush(_handle);
wl_display_disconnect(_handle);
}
_compositor = nullptr;
_registry = nullptr;
_handle = nullptr;
libwayland::unload_symbols(_platform);
}
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_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);
} else if (interface == "wp_fifo_manager_v1") {
device->_fifo = true;
}
}
void wayland_display::listen_global_remove(void*, wl_registry*, uint32_t) {
}
void wayland_display::listen_seat(void*, wl_seat*, uint32_t) {
}
}

View File

@@ -1,86 +0,0 @@
// =====================================================================================================================
// 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/lib/headers/wayland-client-protocols.h>
#include <fennec/platform/linux/wayland/lib/loader.h>
#define FENNEC_LIB(name) bool FENNEC_HAS_LIB_##name;
#define FENNEC_SYMBOL(ret, fn, ...) using WAYLAND_sym_##fn = ret(*)(__VA_ARGS__); \
WAYLAND_sym_##fn WAYLAND_##fn;
#define FENNEC_GLOBAL(type, name) type* WAYLAND_##name;
#include <fennec/platform/linux/wayland/lib/sym.h>
namespace fennec
{
namespace libwayland
{
using shared_object = platform::shared_object;
struct shared_lib {
shared_object* obj;
const cstring name;
};
static int _load_count = 0;
// Create private variables
#define FENNEC_LIB(lib) static shared_lib _FENNEC_LIB_##lib = { nullptr, FENNEC_LIB_##lib };
#include <fennec/platform/linux/wayland/lib/sym.h>
bool load_symbols(platform* platform) {
if (_load_count++ != 0) {
return true;
}
shared_lib* current_lib = nullptr;
#define FENNEC_LIB(lib) _FENNEC_LIB_##lib.obj = platform->load_object(_FENNEC_LIB_##lib.name); \
FENNEC_HAS_LIB_##lib = _FENNEC_LIB_##lib.obj != nullptr; \
if(not FENNEC_HAS_LIB_##lib) { \
unload_symbols(platform); \
return false; \
} \
current_lib = &_FENNEC_LIB_##lib;
#define FENNEC_SYMBOL(ret, fn, ...) WAYLAND_##fn = (WAYLAND_sym_##fn)(platform->find_symbol(current_lib->obj, #fn)); \
assertf(WAYLAND_##fn != nullptr, "Failed to find symbol: " #fn);
#define FENNEC_GLOBAL(type, name) WAYLAND_##name = (type*)(platform->find_symbol(current_lib->obj, #name)); \
assertf(WAYLAND_##name != nullptr, "Failed to find global: " #name);
#include <fennec/platform/linux/wayland/lib/sym.h>
return true;
}
void unload_symbols(platform* platform) {
if (--_load_count != 0) {
return;
}
#define FENNEC_LIB(lib) platform->unload_object(_FENNEC_LIB_##lib.obj); \
_FENNEC_LIB_##lib.obj = nullptr;
#define FENNEC_SYMBOL(ret, fn, ...) WAYLAND_##fn = nullptr;
#define FENNEC_GLOBAL(type, name) WAYLAND_##name = nullptr;
#include <fennec/platform/linux/wayland/lib/sym.h>
}
}
}

View File

@@ -1,139 +0,0 @@
// =====================================================================================================================
// 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/gfxcontext.h>
#include <fennec/platform/interface/gfxsurface.h>
#include <fennec/platform/linux/wayland/window.h>
#include <fennec/platform/linux/wayland/lib/wayland.h>
namespace fennec
{
bool wayland_window::running() {
return _surface != nullptr;
}
void wayland_window::configure(const config& config) {
_config = config;
}
bool wayland_window::initialize(bool) {
wayland_display* display = static_cast<wayland_display*>(_display);
_handle = wl_compositor_create_surface(display->get_compositor());
_surface = display->get_context()->create_surface(this);
return false;
}
bool wayland_window::shutdown() {
delete _surface;
wl_surface_destroy(_handle);
_display = nullptr;
_surface = nullptr;
_shell = nullptr;
_handle = nullptr;
return false;
}
bool wayland_window::set_title(const cstring& title) {
if (not _config) {
return true;
}
_config->title = title;
wl_shell_surface_set_title(_shell, _config->title.cstr());
return false;
}
bool wayland_window::set_title(const string& title) {
if (not _config) {
return true;
}
_config->title = title;
wl_shell_surface_set_title(_shell, _config->title.cstr());
return false;
}
bool wayland_window::set_width(size_t w) {
if (not _config) {
return true;
}
_config->width = w;
_surface->resize(_config->width, _config->height);
return false;
}
bool wayland_window::set_height(size_t h) {
if (not _config) {
return true;
}
_config->height = h;
_surface->resize(_config->width, _config->height);
return false;
}
bool wayland_window::resize(size_t w, size_t h) {
if (not _config) {
return true;
}
_config->width = w;
_config->height = h;
_surface->resize(_config->width, _config->height);
return false;
}
bool wayland_window::set_resizable(bool) {
return false; // TODO
}
bool wayland_window::set_fullscreen_mode(fullscreen_mode) {
return false; // TODO
}
bool wayland_window::grab_keyboard(bool) {
return false; // TODO
}
bool wayland_window::grab_mouse(bool) {
return false; // TODO
}
bool wayland_window::block_screensaver(bool) {
return false; // TODO
}
wayland_window::wayland_window(wayland_display* display, wayland_window* parent)
: window(display, parent, this)
, _handle()
, _shell()
, _nfs_width(0), _nfs_height(0) {
}
wayland_window::~wayland_window() {
wayland_window::shutdown();
}
}

View File

@@ -1,87 +0,0 @@
// =====================================================================================================================
// 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/xkb/lib/xkb.h>
#include <fennec/platform/linux/xkb/lib/loader.h>
#include <fennec/platform/interface/platform.h>
#define FENNEC_LIB(name) bool FENNEC_HAS_LIB_##name;
#define FENNEC_SYMBOL(ret, fn, ...) using XKB_sym_##fn = ret(*)(__VA_ARGS__); \
XKB_sym_##fn XKB_##fn;
#define FENNEC_GLOBAL(type, name) type* XKB_##name;
#include <fennec/platform/linux/xkb/lib/sym.h>
namespace fennec
{
namespace libxkbcommon
{
using shared_object = platform::shared_object;
struct shared_lib {
shared_object* obj;
const cstring name;
};
static int _load_count = 0;
// Create private variables
#define FENNEC_LIB(lib) static shared_lib _FENNEC_LIB_##lib = { nullptr, FENNEC_LIB_##lib };
#include <fennec/platform/linux/xkb/lib/sym.h>
bool load_symbols(platform* platform) {
if (_load_count++ != 0) {
return true;
}
shared_lib* current_lib = nullptr;
#define FENNEC_LIB(lib) _FENNEC_LIB_##lib.obj = platform->load_object(_FENNEC_LIB_##lib.name); \
FENNEC_HAS_LIB_##lib = _FENNEC_LIB_##lib.obj != nullptr; \
if(not FENNEC_HAS_LIB_##lib) { \
unload_symbols(platform); \
return false; \
} \
current_lib = &_FENNEC_LIB_##lib;
#define FENNEC_SYMBOL(ret, fn, ...) XKB_##fn = (XKB_sym_##fn)(platform->find_symbol(current_lib->obj, #fn)); \
assertf(XKB_##fn != nullptr, "Failed to find symbol: " #fn);
#define FENNEC_GLOBAL(type, name) XKB_##name = (type*)(platform->find_symbol(current_lib->obj, #name)); \
assertf(XKB_##name != nullptr, "Failed to find global: " #name);
#include <fennec/platform/linux/xkb/lib/sym.h>
return true;
}
void unload_symbols(platform* platform) {
if (--_load_count != 0) {
return;
}
#define FENNEC_LIB(lib) platform->unload_object(_FENNEC_LIB_##lib.obj); \
_FENNEC_LIB_##lib.obj = nullptr;
#define FENNEC_SYMBOL(ret, fn, ...) XKB_##fn = nullptr;
#define FENNEC_GLOBAL(type, name) XKB_##name = nullptr;
#include <fennec/platform/linux/xkb/lib/sym.h>
}
}
}

View File

@@ -1,166 +0,0 @@
// =====================================================================================================================
// 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/langproc/filesystem/file.h>
#include <fennec/lang/startup.h>
#include <fennec/platform/interface/display.h>
#include <fennec/platform/interface/platform.h>
#include <fennec/platform/opengl/egl/context.h>
#include <fennec/platform/opengl/egl/surface.h>
#include <GL/gl.h>
namespace fennec
{
static gfxcontext* _create_egl_context(display* display) {
eglcontext* ctx = new eglcontext(display);
if (not ctx->connected()) {
delete ctx, ctx = nullptr;
}
return ctx;
}
STATIC_CONSTRUCTOR(_egl_init) {
platform::add_driver(_create_egl_context, 1);
}
eglcontext::eglcontext(display* display)
: gfxcontext(display, "EGL", this)
, _egldisplay(nullptr), _eglcontext(nullptr)
, _eglconfig(), _eglvmajor(0), _eglvminor(0)
, _eglctype(0), _extensions(nullptr) {
// Get the display format
const display::pixel_format& fmt = _display->get_color_format();
// Currently empty
EGLint context_attrs[] = {
EGL_NONE
};
// Configure the depth and rgb bit-depth
EGLint config_attrs[] = {
EGL_SURFACE_TYPE,
EGL_WINDOW_BIT,
EGL_DEPTH_SIZE, fmt.depth,
EGL_RED_SIZE, fmt.r,
EGL_RED_SIZE, fmt.g,
EGL_RED_SIZE, fmt.b,
EGL_RENDERABLE_TYPE,
EGL_OPENGL_BIT, // 7
EGL_NONE
};
// Attempt to retrieve an egl display from the native display
_egldisplay = eglGetDisplay(_display->get_native_handle());
if (_egldisplay == nullptr) {
cleanup();
return;
}
// Attempt to initialize egl
if (not eglInitialize(_egldisplay, nullptr, nullptr)) {
cleanup();
return;
}
// Attempt to bind to Core OpenGL, otherwise OpenGL ES
if (not eglBindAPI(EGL_OPENGL_API)) {
if (not eglBindAPI(EGL_OPENGL_ES_API)) {
cleanup();
return;
}
config_attrs[7] = EGL_OPENGL_ES_BIT; // Change the support bit to OpenGL ES
}
// Select a configuration
EGLint n;
if (not eglChooseConfig(_egldisplay, config_attrs, &_eglconfig, 1, &n)) {
cleanup();
return;
}
// Create the context
_eglcontext = eglCreateContext(_egldisplay, _eglconfig, EGL_NO_CONTEXT, context_attrs);
if (_eglcontext == nullptr) {
cleanup();
return;
}
// make this the current context so we can retrieve the information below
eglMakeCurrent(_egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, _eglcontext);
// Query available extensions
const char* ptr = eglQueryString(_egldisplay, EGL_EXTENSIONS);
_extensions = { ptr, strlen(ptr) + 1 };
// Query the context and version
eglQueryContext(_egldisplay, _eglcontext, EGL_CONTEXT_CLIENT_TYPE, &_eglctype);
glGetIntegerv(GL_MAJOR_VERSION, &_eglvmajor);
glGetIntegerv(GL_MINOR_VERSION, &_eglvminor);
}
eglcontext::~eglcontext() {
cleanup();
}
bool eglcontext::connected() {
return _eglcontext != nullptr;
}
const cstring& eglcontext::get_name() {
static constexpr cstring opengl = "OpenGL";
static constexpr cstring gles = "GLES";
static constexpr cstring openvg = "OpenVG"; // this should never be used
switch (_eglctype) {
default:
case EGL_OPENGL_API: return opengl;
case EGL_OPENGL_ES_API: return gles;
case EGL_OPENVG_API: return openvg;
}
}
bool eglcontext::check_extension(const cstring& ext) {
return _extensions.find(ext) != _extensions.size();
}
gfxsurface* eglcontext::create_surface(window* window) {
return new eglsurface(this, window);
}
void eglcontext::make_current(gfxsurface* surface) {
eglsurface* eglsurface = static_cast<fennec::eglsurface*>(surface);
eglMakeCurrent(_egldisplay, eglsurface->get_egl_surface(), eglsurface->get_egl_surface(), _eglcontext);
}
void eglcontext::cleanup() {
eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(_display, _eglcontext);
eglTerminate(_display);
eglReleaseThread();
_egldisplay = nullptr;
_eglconfig = nullptr;
_eglcontext = nullptr;
_eglvmajor = 0;
_eglvminor = 0;
}
}

View File

@@ -1,66 +0,0 @@
// =====================================================================================================================
// 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/opengl/egl/surface.h>
#include <fennec/platform/linux/wayland/lib/wayland.h>
namespace fennec
{
eglsurface::~eglsurface() {
if (_window->is_type<wayland_window>()) {
wl_egl_window_destroy(static_cast<wl_egl_window*>(_handle));
}
}
void eglsurface::resize(size_t width, size_t height) {
gfxsurface::resize(width, height);
if (_window->is_type<wayland_window>()) {
wl_egl_window_resize(static_cast<wl_egl_window*>(_handle), width, height, 0, 0);
}
}
eglsurface::eglsurface(eglcontext* context, window* window)
: gfxsurface(context, window, this)
, _handle(nullptr)
, _surface(nullptr) {
const window::config& config = window->get_config();
if (window->is_type<wayland_window>()) {
_handle = wl_egl_window_create(window->get_native_handle(), config.width, config.height);
}
assert(
_handle != nullptr,
"Failed to create egl window!"
);
eglCreateWindowSurface(
context->get_egl_display(),
context->get_egl_config(),
reinterpret_cast<EGLNativeWindowType>(_handle),
nullptr
);
assert(
EGL_TRUE == eglMakeCurrent(context->get_egl_display(), _surface, _surface, context->get_egl_context()),
"Failed to create egl window!"
);
}
}

View File

@@ -21,8 +21,6 @@
#include "../test.h"
#include <fennec/platform/interface/display.h>
#include <fennec/platform/interface/gfxcontext.h>
#include <fennec/platform/interface/platform.h>
@@ -31,37 +29,6 @@ namespace fennec::test
inline void fennec_test_platform() {
platform* instance = platform::instance();
instance->initialize();
display* display = instance->get_display();
fennec_test_run(display != nullptr, true);
fennec_test_run(display->get_context() != nullptr, true);
gfxcontext* gfxcontext = display->get_context();
std::cout << gfxcontext->get_name() << " ";
std::cout << gfxcontext->get_version_major() << ".";
std::cout << gfxcontext->get_version_minor() << std::endl;
window::config winconfig = {
string{"fennec_test_platform"},
window::flags_none,
1280, 720,
window::fullscreen_mode::windowed
};
window* window = display->create_window(nullptr);
fennec_test_run(window != nullptr, true);
window->configure(winconfig);
window->initialize(false);
fennec_test_run(window->running(), true);
delete window;
instance->shutdown();
}
}