Compare commits
2 Commits
custom_pla
...
992a02db3e
| Author | SHA1 | Date | |
|---|---|---|---|
| 992a02db3e | |||
| e1eaf97961 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -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
|
||||
|
||||
@@ -17,20 +17,10 @@
|
||||
# ======================================================================================================================
|
||||
|
||||
cmake_minimum_required(VERSION 3.30)
|
||||
|
||||
project(fennec)
|
||||
|
||||
# External dependencies should be loaded here
|
||||
add_subdirectory(external/cpptrace)
|
||||
|
||||
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."
|
||||
COMMENT "Running dependencies."
|
||||
)
|
||||
|
||||
macro(fennec_add_sources)
|
||||
list(APPEND FENNEC_EXTRA_SOURCES ${ARGN})
|
||||
endmacro()
|
||||
@@ -43,6 +33,26 @@ macro(fennec_add_link_libraries)
|
||||
list(APPEND FENNEC_LINK_LIBRARIES ${ARGN})
|
||||
endmacro()
|
||||
|
||||
macro(fennec_add_shared_libraries)
|
||||
list(APPEND FENNEC_SHARED_LIBRARIES ${ARGN})
|
||||
endmacro()
|
||||
|
||||
macro(fennec_add_link_options)
|
||||
list(APPEND FENNEC_PRIVATE_LINK_OPTIONS ${ARGN})
|
||||
endmacro()
|
||||
|
||||
# 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)
|
||||
|
||||
add_custom_target(fennec-dependencies
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Running dependencies."
|
||||
COMMENT "Running dependencies."
|
||||
)
|
||||
|
||||
# include scripts
|
||||
include("${FENNEC_SOURCE_DIR}/cmake/version.cmake")
|
||||
include("${FENNEC_SOURCE_DIR}/cmake/platform.cmake")
|
||||
@@ -62,7 +72,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})
|
||||
@@ -84,6 +94,13 @@ add_library(fennec STATIC
|
||||
include/fennec/scene/component.h
|
||||
|
||||
|
||||
# Renderers ============================================================================================================
|
||||
include/fennec/renderers/interface/forward.h
|
||||
|
||||
include/fennec/renderers/interface/gfxcontext.h
|
||||
include/fennec/renderers/interface/gfxsubpass.h
|
||||
|
||||
|
||||
# CONTAINERS ===========================================================================================================
|
||||
include/fennec/containers/containers.h
|
||||
|
||||
@@ -124,7 +141,7 @@ add_library(fennec STATIC
|
||||
include/fennec/lang/type_sequences.h
|
||||
include/fennec/lang/type_traits.h
|
||||
include/fennec/lang/type_transforms.h
|
||||
include/fennec/lang/typeuuid.h
|
||||
include/fennec/lang/typed.h
|
||||
include/fennec/lang/types.h
|
||||
include/fennec/lang/utility.h
|
||||
include/fennec/lang/integer.h
|
||||
@@ -212,14 +229,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
|
||||
include/fennec/platform/interface/window.h
|
||||
|
||||
|
||||
# EXTRA SOURCES ========================================================================================================
|
||||
|
||||
${FENNEC_EXTRA_SOURCES}
|
||||
include/fennec/containers/bintree.h
|
||||
)
|
||||
|
||||
add_dependencies(fennec metaprogramming fennec-dependencies)
|
||||
@@ -235,10 +251,16 @@ target_link_options(fennec PRIVATE ${FENNEC_PRIVATE_LINK_OPTIONS}) # Do not comp
|
||||
|
||||
target_link_libraries(fennec PRIVATE
|
||||
${FENNEC_LINK_LIBRARIES}
|
||||
${FENNEC_SHARED_LIBRARIES}
|
||||
|
||||
cpptrace::cpptrace
|
||||
)
|
||||
|
||||
foreach (_LIB IN ITEMS ${FENNEC_SHARED_LIBRARIES})
|
||||
add_custom_command(TARGET fennec POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_LINKER_FILE:${_LIB}> ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
|
||||
)
|
||||
endforeach ()
|
||||
|
||||
|
||||
# DOXYGEN ==============================================================================================================
|
||||
|
||||
@@ -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]])
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -32,26 +32,3 @@ if(TARGET OpenGL::GL AND TARGET GLEW::GLEW)
|
||||
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()
|
||||
30
cmake/sdl.cmake
Normal file
30
cmake/sdl.cmake
Normal file
@@ -0,0 +1,30 @@
|
||||
# ======================================================================================================================
|
||||
# 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(${FENNEC_SOURCE_DIR}/external/SDL)
|
||||
|
||||
fennec_add_sources(
|
||||
include/fennec/platform/sdl/sdlwindow.h
|
||||
)
|
||||
|
||||
fennec_add_shared_libraries(
|
||||
SDL3::SDL3-shared
|
||||
)
|
||||
|
||||
@@ -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()
|
||||
@@ -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
1
external/SDL
vendored
Submodule
Submodule external/SDL added at dee2414ee7
299
include/fennec/containers/bintree.h
Normal file
299
include/fennec/containers/bintree.h
Normal file
@@ -0,0 +1,299 @@
|
||||
// =====================================================================================================================
|
||||
// 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 bintree.h
|
||||
/// \brief
|
||||
///
|
||||
///
|
||||
/// \details
|
||||
/// \author Medusa Slockbower
|
||||
///
|
||||
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||
///
|
||||
///
|
||||
|
||||
#ifndef FENNEC_CONTAINERS_BINTREE_H
|
||||
#define FENNEC_CONTAINERS_BINTREE_H
|
||||
|
||||
#include <fennec/containers/dynarray.h>
|
||||
#include <fennec/containers/list.h>
|
||||
#include <fennec/containers/optional.h>
|
||||
#include <fennec/math/exponential.h>
|
||||
#include <fennec/memory/allocator.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
template<typename TypeT, class AllocT>
|
||||
struct bintree {
|
||||
|
||||
// Definitions =========================================================================================================
|
||||
protected:
|
||||
struct node;
|
||||
|
||||
public:
|
||||
using value_t = TypeT;
|
||||
using alloc_t = allocator_traits<AllocT>::template rebind<node>;
|
||||
static constexpr size_t root = 0;
|
||||
static constexpr size_t npos = -1;
|
||||
|
||||
protected:
|
||||
struct node {
|
||||
optional<value_t> value;
|
||||
size_t parent, left, right;
|
||||
size_t depth;
|
||||
|
||||
constexpr node()
|
||||
: value(nullopt)
|
||||
, parent(npos), left(npos), right(npos)
|
||||
, depth(0) {
|
||||
}
|
||||
|
||||
template<typename...ArgsT>
|
||||
constexpr node(size_t p, size_t l, size_t r, size_t d, ArgsT&&...args)
|
||||
: value(fennec::forward<ArgsT>(args)...)
|
||||
, parent(p), left(l), right(r)
|
||||
, depth(d) {
|
||||
}
|
||||
|
||||
constexpr ~node() {
|
||||
parent = npos;
|
||||
left = npos;
|
||||
right = npos;
|
||||
depth = npos;
|
||||
}
|
||||
};
|
||||
|
||||
using table_t = allocation<node, alloc_t>;
|
||||
using freed_t = list<size_t, alloc_t>;
|
||||
|
||||
// Navigation ==========================================================================================================
|
||||
public:
|
||||
|
||||
///
|
||||
/// \details \f$O(1)\f$
|
||||
/// \param i The node id
|
||||
/// \returns The parent of node `i`
|
||||
constexpr size_t parent(size_t i) const {
|
||||
if (i >= _table.size()) {
|
||||
return false;
|
||||
}
|
||||
return _table[i].parent;
|
||||
}
|
||||
|
||||
///
|
||||
/// \details \f$O(1)\f$
|
||||
/// \param i The node id
|
||||
/// \returns The left child of node `i`
|
||||
constexpr size_t left(size_t i) const {
|
||||
if (i >= _table.size()) {
|
||||
return false;
|
||||
}
|
||||
return _table[i].left;
|
||||
}
|
||||
|
||||
///
|
||||
/// \details \f$O(1)\f$
|
||||
/// \param i The node id
|
||||
/// \returns The right child of node `i`
|
||||
constexpr size_t right(size_t i) const {
|
||||
if (i >= _table.size()) {
|
||||
return false;
|
||||
}
|
||||
return _table[i].right;
|
||||
}
|
||||
|
||||
///
|
||||
/// \details \f$O(\log n)\f$
|
||||
/// \param i The node id
|
||||
/// \returns The depth of node `i`
|
||||
constexpr size_t depth(size_t i) const {
|
||||
if (i >= _table.size()) {
|
||||
return npos;
|
||||
}
|
||||
return _table[i].depth;
|
||||
}
|
||||
|
||||
|
||||
// Access ==============================================================================================================
|
||||
|
||||
///
|
||||
/// \details \f$O(1)\f$
|
||||
/// \param i The node id
|
||||
/// \returns `nullptr` if node `i` does not exist, otherwise, a pointer to the value of node `i`
|
||||
constexpr value_t* operator[](size_t i) {
|
||||
if (i >= _table.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
return _table[i] ? &*_table[i] : nullptr;
|
||||
}
|
||||
|
||||
///
|
||||
/// \details Const Access, \f$O(1)\f$
|
||||
/// \param i The node id
|
||||
/// \returns `nullptr` if node `i` does not exist, otherwise, a pointer to the value of node `i`
|
||||
constexpr const value_t* operator[](size_t i) const {
|
||||
if (i >= _table.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
return _table[i] ? &*_table[i] : nullptr;
|
||||
}
|
||||
|
||||
// Modifiers ===========================================================================================================
|
||||
|
||||
///
|
||||
/// \brief Move Left Insertion, constructs a new node as the left child of `p`
|
||||
/// \details If the left node of `p` already exists, the move assignment operator is used instead
|
||||
/// \param p The parent node
|
||||
/// \param val The object to move into the new node
|
||||
/// \returns The id of the new node
|
||||
constexpr size_t insert_left(size_t p, value_t&& val) {
|
||||
return this->_insert_left(p, fennec::forward<value_t>(val));
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Copy Left Insertion, constructs a new node as the left child of `p`
|
||||
/// \details If the left node of `p` already exists, the copy assignment operator is used instead
|
||||
/// \param p The parent node
|
||||
/// \param val The object to copy to the new node
|
||||
/// \returns The id of the new node
|
||||
constexpr size_t insert_left(size_t p, const value_t& val) {
|
||||
return this->_insert_left(p,, val);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Move Left Insertion, constructs a new node as the left child of `p`
|
||||
/// \details If the left node of `p` already exists, the move assignment operator is used instead
|
||||
/// \param p The parent node
|
||||
/// \param args The arguments to construct the new node with
|
||||
/// \returns The id of the new node
|
||||
template<typename...ArgsT>
|
||||
constexpr size_t emplace_left(size_t p, ArgsT&&...args) {
|
||||
return this->_insert_left(p, fennec::forward<ArgsT>(args)...);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Perform a Left Tree Rotation at `i`
|
||||
/// \param i The root node for the rotation
|
||||
constexpr void rotate_left(size_t i) {
|
||||
if (i >=_table.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t l = i;
|
||||
size_t p = parent(l);
|
||||
size_t r = right(l);
|
||||
|
||||
if (p == npos) {
|
||||
_root = r;
|
||||
} else if (l == _table[p].left) {
|
||||
_table[p].left = r;
|
||||
} else {
|
||||
_table[p].right = r;
|
||||
}
|
||||
|
||||
_table[l].parent = r;
|
||||
_table[l].right = _table[r].left;
|
||||
|
||||
_table[r].parent = p;
|
||||
_table[r].left = l;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Perform a Right Tree Rotation at `i`
|
||||
/// \param i The root node for the rotation
|
||||
constexpr void rotate_right(size_t i) {
|
||||
if (i >=_table.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t r = i;
|
||||
size_t p = parent(r);
|
||||
size_t l = left(r);
|
||||
|
||||
if (p == npos) {
|
||||
_root = l;
|
||||
} else if (r == _table[p].left) {
|
||||
_table[p].left = l;
|
||||
} else {
|
||||
_table[p].right = l;
|
||||
}
|
||||
|
||||
_table[r].parent = l;
|
||||
_table[r].left = _table[l].right;
|
||||
|
||||
_table[l].parent = p;
|
||||
_table[l].right = r;
|
||||
}
|
||||
|
||||
protected:
|
||||
table_t _table;
|
||||
freed_t _freed;
|
||||
size_t _root, _size;
|
||||
|
||||
constexpr void _next_free() {
|
||||
size_t i = _size;
|
||||
if (not _freed.empty()) {
|
||||
i = _freed.front();
|
||||
_freed.pop_front();
|
||||
}
|
||||
if (i >= _table.size()) {
|
||||
_table.reallocate(2 * fennec::max(_table.size(), 4));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename...ArgsT>
|
||||
constexpr size_t _insert_left(size_t p, ArgsT&&...args) {
|
||||
size_t i = left(p);
|
||||
if (i == npos) {
|
||||
i = _next_free();
|
||||
_table[i].value.emplace(fennec::forward<ArgsT>(args)...);
|
||||
} else {
|
||||
size_t d = 1;
|
||||
if (p != npos) {
|
||||
d = depth(p) + 1;
|
||||
_table[p].left = i;
|
||||
}
|
||||
fennec::construct(&_table[i], p, npos, npos, d);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename...ArgsT>
|
||||
constexpr size_t _insert_right(size_t p, ArgsT&&...args) {
|
||||
size_t i = right(p);
|
||||
if (i == npos) {
|
||||
i = _next_free();
|
||||
_table[i].value.emplace(fennec::forward<ArgsT>(args)...);
|
||||
if (p == npos || _root == npos) {
|
||||
_root = i;
|
||||
}
|
||||
} else {
|
||||
size_t d = 1;
|
||||
if (p != npos) {
|
||||
d = depth(p) + 1;
|
||||
_table[p].right = i;
|
||||
}
|
||||
fennec::construct(&_table[i], p, npos, npos, d);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_CONTAINERS_BINTREE_H
|
||||
@@ -1,586 +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 multiset.h
|
||||
/// \brief A header containing the definition for a set of repeating values
|
||||
///
|
||||
///
|
||||
/// \details
|
||||
/// \author Medusa Slockbower
|
||||
///
|
||||
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||
///
|
||||
///
|
||||
|
||||
#ifndef FENNEC_CONTAINERS_MULTISET_H
|
||||
#define FENNEC_CONTAINERS_MULTISET_H
|
||||
|
||||
// https://programming.guide/robin-hood-hashing.html
|
||||
|
||||
#include <fennec/containers/optional.h>
|
||||
#include <fennec/containers/multiset.h>
|
||||
#include <fennec/lang/compare.h>
|
||||
#include <fennec/math/ext/primes.h>
|
||||
#include <fennec/memory/allocator.h>
|
||||
#include <fennec/lang/hashing.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
///
|
||||
///
|
||||
/// \brief A Data Structure that defines a set of elements that may repeat
|
||||
/// \details
|
||||
/// | Property | Value |
|
||||
/// |:----------:|:----------:|
|
||||
/// | stable | ⛔ |
|
||||
/// | dynamic | ✅ |
|
||||
/// | homogenous | ✅ |
|
||||
/// | distinct | ⛔ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
/// | linear | ✅ |
|
||||
/// | access | \f$O(1)\f$ |
|
||||
/// | find | \f$O(1)\f$ |
|
||||
/// | insertion | \f$O(1)\f$ |
|
||||
/// | deletion | \f$O(1)\f$ |
|
||||
///
|
||||
/// \tparam TypeT The type to contain
|
||||
template<typename TypeT, class Hash = hash<TypeT>, class Equals = equality<TypeT>, class Alloc = allocator<TypeT>>
|
||||
struct multiset {
|
||||
|
||||
// Definitions =========================================================================================================
|
||||
public:
|
||||
using alloc_t = typename allocator_traits<Alloc>::template rebind<TypeT>;
|
||||
using hash_t = Hash;
|
||||
using equal_t = Equals;
|
||||
using elem_t = TypeT;
|
||||
|
||||
class iterator;
|
||||
class value_iterator;
|
||||
static constexpr size_t npos = -1;
|
||||
static constexpr double default_load = 0.8;
|
||||
|
||||
private:
|
||||
struct node {
|
||||
optional<elem_t> value;
|
||||
int psl;
|
||||
|
||||
constexpr node() = default;
|
||||
constexpr ~node() = default;
|
||||
};
|
||||
|
||||
// Constructors ========================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Constructors & Destructor
|
||||
/// @{
|
||||
|
||||
///
|
||||
/// \brief Default Constructor, initializes empty multiset
|
||||
constexpr multiset()
|
||||
: _alloc()
|
||||
, _hash()
|
||||
, _size(0)
|
||||
, _sumpsl(0)
|
||||
, _load(default_load) {
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief Hash Copy Constructor, initializes empty multiset with a hash
|
||||
constexpr multiset(const hash_t& hash)
|
||||
: _alloc()
|
||||
, _hash(hash)
|
||||
, _size(0)
|
||||
, _sumpsl(0)
|
||||
, _load(default_load) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Hash Move Constructor, initializes empty multiset with a hash
|
||||
constexpr multiset(hash_t&& hash) noexcept
|
||||
: _alloc()
|
||||
, _hash(hash)
|
||||
, _size(0)
|
||||
, _sumpsl(0)
|
||||
, _load(default_load) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Alloc Copy Constructor, initializes empty multiset with an allocator
|
||||
constexpr multiset(const alloc_t& alloc)
|
||||
: _alloc(alloc)
|
||||
, _hash()
|
||||
, _size(0)
|
||||
, _sumpsl(0)
|
||||
, _load(default_load) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Alloc Move Constructor, initializes empty multiset with an allocator
|
||||
constexpr multiset(alloc_t&& alloc) noexcept
|
||||
: _alloc(alloc)
|
||||
, _hash()
|
||||
, _size(0)
|
||||
, _sumpsl(0)
|
||||
, _load(default_load) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Hash Alloc Copy Constructor, initializes empty multiset with a hash and allocator
|
||||
constexpr multiset(const hash_t& hash, const alloc_t& alloc)
|
||||
: _alloc(alloc)
|
||||
, _hash(hash)
|
||||
, _size(0)
|
||||
, _sumpsl(0)
|
||||
, _load(default_load) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Hash Copy Alloc Move Constructor, initializes empty multiset with a hash and allocator
|
||||
constexpr multiset(const hash_t& hash, alloc_t&& alloc) noexcept
|
||||
: _alloc(alloc)
|
||||
, _hash(hash)
|
||||
, _size(0)
|
||||
, _sumpsl(0)
|
||||
, _load(default_load) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Hash Move Alloc Move Constructor, initializes empty multiset with a hash and allocator
|
||||
constexpr multiset(hash_t&& hash, alloc_t&& alloc) noexcept
|
||||
: _alloc(alloc)
|
||||
, _hash(hash)
|
||||
, _size(0)
|
||||
, _sumpsl(0)
|
||||
, _load(default_load) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Hash Move Alloc Copy Constructor, initializes empty multiset with a hash and allocator
|
||||
constexpr multiset(hash_t&& hash, const alloc_t& alloc) noexcept
|
||||
: _alloc(alloc)
|
||||
, _hash(hash)
|
||||
, _size(0)
|
||||
, _sumpsl(0)
|
||||
, _load(default_load) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Set Copy Constructor
|
||||
/// \param multiset Set to copy
|
||||
constexpr multiset(const multiset& multiset)
|
||||
: _alloc( multiset._alloc)
|
||||
, _hash( multiset._hash)
|
||||
, _size( multiset._size)
|
||||
, _sumpsl( multiset._sumpsl)
|
||||
, _load( multiset._load) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Set Move Constructor
|
||||
/// \param multiset Set to move
|
||||
constexpr multiset(multiset&& multiset) noexcept
|
||||
: _alloc(fennec::move( multiset._alloc))
|
||||
, _hash(fennec::move( multiset._hash))
|
||||
, _size(fennec::move( multiset._size))
|
||||
, _sumpsl( multiset._sumpsl)
|
||||
, _load( multiset._load) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Destructor, destructs all elements and releases the allocation
|
||||
constexpr ~multiset() {
|
||||
for (size_t i = 0; i < capacity(); ++i) {
|
||||
_alloc[i].value = nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
// Properties ==========================================================================================================
|
||||
|
||||
/// \name Properties
|
||||
/// @{
|
||||
|
||||
///
|
||||
/// \returns Size of the multiset in elements
|
||||
constexpr size_t size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns `true` when the set is empty, `false` otherwise
|
||||
constexpr bool empty() const {
|
||||
return _size == 0;
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns Capacity of the multiset in elements
|
||||
constexpr size_t capacity() const {
|
||||
return _alloc.capacity();
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
// Access ==============================================================================================================
|
||||
|
||||
/// \name Access
|
||||
/// @{
|
||||
|
||||
///
|
||||
/// \brief Find an Element
|
||||
/// \param val Value to find
|
||||
/// \returns An iterator at the location of the first instance of `value`
|
||||
constexpr iterator find(const elem_t& val, size_t c = 0) const {
|
||||
if (capacity() == 0) {
|
||||
return end();
|
||||
}
|
||||
size_t s = _hash(val) % capacity(); // Initial search index
|
||||
int psl = (_size != 0) ? _sumpsl / _size : 0; // Initial psl
|
||||
size_t i = (s + psl) % capacity(); // Median search
|
||||
size_t n = 0;
|
||||
|
||||
// Check the first element;
|
||||
if (_alloc[i].psl >= psl && _alloc[i].value) {
|
||||
if (*_alloc[i].value == val) {
|
||||
return iterator(this, i);
|
||||
}
|
||||
}
|
||||
|
||||
// Loop while there is a value and its psl is greater than our probe
|
||||
while (c > 0) {
|
||||
++n;
|
||||
size_t i0 = (i + capacity() - n) % capacity(); // Prevent index underflow
|
||||
size_t i1 = (i + n) % capacity();
|
||||
int p0 = psl - n, p1 = psl + n;
|
||||
bool c0 = p0 >= 0 && _alloc[i0].psl >= p0, c1 = _alloc[i1].psl >= p1; // Check that we are in range
|
||||
|
||||
if (c0 && _alloc[i0].value) {
|
||||
if (*_alloc[i0].value == val) {
|
||||
if (c-- == 0) {
|
||||
return iterator(this, i0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (c1 && _alloc[i1].value) {
|
||||
if (*_alloc[i1].value == val) {
|
||||
if (c-- == 0) {
|
||||
return iterator(this, i1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (not(c0 or c1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return iterator(this, npos);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Check if a multiset contains a value
|
||||
/// \param val Value to check
|
||||
/// \returns `true` if `val` can be found, `false` otherwise
|
||||
constexpr bool contains(const elem_t& val) const {
|
||||
return this->find(val) != end();
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Iterator Access
|
||||
/// \param it Location to access
|
||||
/// \returns A pointer to the element, `nullptr` if not found.
|
||||
/// The value should not be changed in a manner that will change the hash of the element.
|
||||
constexpr elem_t* at(const iterator& it) {
|
||||
if (it == end()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (not _alloc[it._i].value) {
|
||||
return nullptr;
|
||||
}
|
||||
return &*_alloc[it._i].value;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Iterator Const Access
|
||||
/// \param it Location to access
|
||||
/// \returns A const-qualified pointer to the element, `nullptr` if not found.
|
||||
constexpr const elem_t* at(const iterator& it) const {
|
||||
if (not _alloc[it._i].value) return nullptr;
|
||||
return &*_alloc[it._i].value;
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
// Modifiers ===========================================================================================================
|
||||
|
||||
/// \name Modifiers
|
||||
/// @{
|
||||
|
||||
///
|
||||
/// \brief Move Insertion
|
||||
/// \param val Value to insert
|
||||
constexpr void insert(elem_t&& val) {
|
||||
this->_insert(fennec::forward<elem_t>(val));
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Copy Insertion
|
||||
/// \param val Value to insert
|
||||
constexpr void insert(const elem_t& val) {
|
||||
this->_insert(val);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Emplace Insertion
|
||||
/// \tparam ArgsT Argument types
|
||||
/// \param args Arguments to construct with
|
||||
template<typename...ArgsT>
|
||||
constexpr void emplace(ArgsT&&...args) {
|
||||
this->_insert(fennec::forward<ArgsT>(args)...);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Element Erase
|
||||
/// \param it Location to erase
|
||||
constexpr void erase(iterator it) {
|
||||
size_t i = it._i;
|
||||
if (i >= capacity()) {
|
||||
return;
|
||||
} // These are separated due to compilers being inconsistent
|
||||
if (not _alloc[i].value) {
|
||||
return;
|
||||
}
|
||||
|
||||
_alloc[i].value = nullopt;
|
||||
_sumpsl -= _alloc[i].psl;
|
||||
--_size;
|
||||
size_t p = i;
|
||||
while (_alloc[i = (i + 1) % capacity()].value) {
|
||||
if (_alloc[i].psl == 0) break;
|
||||
|
||||
fennec::swap(_alloc[i - 1].value, _alloc[i].value);
|
||||
--_alloc[p].psl, --_sumpsl;
|
||||
p = i;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Element Erase
|
||||
/// \param val Value to erase
|
||||
constexpr void erase(const elem_t& val) {
|
||||
this->erase(this->find(val));
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
// ITERATOR ============================================================================================================
|
||||
|
||||
/// \name Iteration
|
||||
/// @{
|
||||
|
||||
///
|
||||
/// \brief C++ Iterator Specification `begin()`
|
||||
/// \returns An iterator for all elements of the set in no particular order
|
||||
constexpr iterator begin() const {
|
||||
iterator it(this, 0);
|
||||
if (not _alloc[it._i].value) {
|
||||
++it;
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief C++ Iterator Specification `end()`
|
||||
/// \returns An iterator representing the end of the set
|
||||
constexpr iterator end() const {
|
||||
return iterator(this, npos);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
///
|
||||
/// \brief Class for Iterating the Set
|
||||
class iterator {
|
||||
public:
|
||||
constexpr ~iterator() {
|
||||
_set = nullptr;
|
||||
}
|
||||
|
||||
// prefix operator
|
||||
constexpr iterator& operator++() {
|
||||
while (++_i < _set->capacity()) {
|
||||
if (_set->_alloc[_i].value) {
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
_i = npos;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr iterator operator++(int) {
|
||||
iterator prev = *this;
|
||||
this->operator++();
|
||||
return prev;
|
||||
}
|
||||
|
||||
constexpr const elem_t& operator*() const {
|
||||
return *_set->_alloc[_i].value;
|
||||
}
|
||||
|
||||
constexpr const elem_t* operator->() const {
|
||||
if (not _set->_alloc[_i].value) return nullptr;
|
||||
return &*_set->_alloc[_i].value;
|
||||
}
|
||||
|
||||
constexpr bool operator==(const iterator& it) const {
|
||||
return _set == it._set and _i == it._i;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(const iterator& it) const {
|
||||
return _set != it._set or _i != it._i;
|
||||
}
|
||||
|
||||
private:
|
||||
const multiset* _set;
|
||||
size_t _i;
|
||||
friend multiset;
|
||||
|
||||
constexpr iterator(const multiset* multiset, size_t i)
|
||||
: _set(multiset)
|
||||
, _i(i) {
|
||||
}
|
||||
};
|
||||
|
||||
class value_iterator {
|
||||
public:
|
||||
constexpr ~value_iterator() {
|
||||
_set = nullptr;
|
||||
}
|
||||
|
||||
// prefix operator
|
||||
constexpr value_iterator& operator++() {
|
||||
while (_psl <= _set->_alloc[_i].psl) {
|
||||
if (not _set->_alloc[_i].value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_i = npos;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr value_iterator operator++(int) {
|
||||
value_iterator prev = *this;
|
||||
this->operator++();
|
||||
return prev;
|
||||
}
|
||||
|
||||
constexpr const elem_t& operator*() const {
|
||||
return *_set->_alloc[_i].value;
|
||||
}
|
||||
|
||||
constexpr const elem_t* operator->() const {
|
||||
if (not _set->_alloc[_i].value) return nullptr;
|
||||
return &*_set->_alloc[_i].value;
|
||||
}
|
||||
|
||||
constexpr bool operator==(const iterator& it) const {
|
||||
return _set == it._set and _i == it._i;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(const iterator& it) const {
|
||||
return _set != it._set or _i != it._i;
|
||||
}
|
||||
|
||||
private:
|
||||
const multiset* _set;
|
||||
size_t _i;
|
||||
int _psl;
|
||||
elem_t _value;
|
||||
friend multiset;
|
||||
|
||||
constexpr value_iterator(const multiset* multiset, size_t i, int psl, const elem_t& value)
|
||||
: _set(multiset)
|
||||
, _i(i)
|
||||
, _value(value) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// PRIVATE =============================================================================================================
|
||||
|
||||
private:
|
||||
constexpr void _expand() {
|
||||
multiset cpy; // Create a new multiset
|
||||
cpy._alloc.callocate(
|
||||
fennec::next_prime2(_alloc.capacity())
|
||||
);
|
||||
|
||||
// rehash
|
||||
for (size_t i = 0; i < capacity(); ++i) {
|
||||
if (_alloc[i].value) {
|
||||
cpy.insert(fennec::move(*_alloc[i].value));
|
||||
}
|
||||
}
|
||||
|
||||
// Swap buffers
|
||||
fennec::swap(_alloc, cpy._alloc);
|
||||
}
|
||||
|
||||
template<typename...ArgsT>
|
||||
constexpr void _insert(ArgsT&&...args) {
|
||||
if (_size == 0 or static_cast<float>(_size) / capacity() >= _load) { // expand when full
|
||||
_expand();
|
||||
}
|
||||
|
||||
elem_t value(fennec::forward<ArgsT>(args)...);
|
||||
size_t i = _hash(value) % capacity(); // Initial search index
|
||||
int psl = 0;
|
||||
while (_alloc[i].value) { // Search for empty cell
|
||||
if (_equal(*_alloc[i].value, value)) { // Check to see if this element is already inserted
|
||||
return;
|
||||
}
|
||||
if (psl > _alloc[i].psl) { // When psl is higher, swap
|
||||
_sumpsl += psl - _alloc[i].psl;
|
||||
fennec::swap(_alloc[i].psl, psl);
|
||||
fennec::swap(*_alloc[i].value, value);
|
||||
}
|
||||
i = (i + 1) % capacity(); ++psl;
|
||||
}
|
||||
_alloc[i].value = fennec::move(value);
|
||||
_sumpsl += (_alloc[i].psl = psl);
|
||||
++_size;
|
||||
}
|
||||
|
||||
allocation<node, alloc_t> _alloc;
|
||||
hash_t _hash;
|
||||
equal_t _equal;
|
||||
size_t _size;
|
||||
size_t _sumpsl;
|
||||
float _load;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_CONTAINERS_SET_H
|
||||
@@ -294,9 +294,35 @@ public:
|
||||
/// \name Modifiers
|
||||
/// @{
|
||||
|
||||
///
|
||||
/// \brief Emplace Assignment, Move overload
|
||||
/// \param val The object to take ownership of
|
||||
constexpr T& emplace(T&& val) {
|
||||
if (_set) {
|
||||
_val = fennec::forward<T>(val);
|
||||
} else {
|
||||
fennec::construct(&_val, fennec::forward<T>(val));
|
||||
_set = true;
|
||||
}
|
||||
return _val;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Emplace Assignment, Copy overload
|
||||
/// \param val The object to copy
|
||||
constexpr T& emplace(const T& val) {
|
||||
if (_set) {
|
||||
_val = val;
|
||||
} else {
|
||||
fennec::construct(&_val, val);
|
||||
_set = true;
|
||||
}
|
||||
return _val;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Emplace Assignment
|
||||
/// \val The optional to move
|
||||
/// \param args The arguments to construct with
|
||||
template<typename...ArgsT>
|
||||
constexpr T& emplace(ArgsT&&...args) {
|
||||
if (_set) {
|
||||
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
|
||||
protected:
|
||||
struct node {
|
||||
optional<TypeT> value;
|
||||
optional<value_t> value;
|
||||
size_t parent, child, prev, next;
|
||||
size_t depth, num_children;
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#define FENNEC_CORE_EVENT_H
|
||||
|
||||
#include <fennec/lang/types.h>
|
||||
#include <fennec/lang/typeuuid.h>
|
||||
#include <fennec/lang/typed.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,9 @@
|
||||
#include <fennec/containers/list.h>
|
||||
#include <fennec/langproc/strings/cstring.h>
|
||||
#include <fennec/langproc/strings/string.h>
|
||||
#include <fennec/lang/typeuuid.h>
|
||||
#include <fennec/lang/typed.h>
|
||||
#include <fennec/platform/interface/fwd.h>
|
||||
#include <fennec/platform/interface/window.h>
|
||||
|
||||
/*
|
||||
* This class should resemble the target platform as a whole. By itself, it will represent the OS, i.e. Linux, Windows,
|
||||
@@ -64,6 +65,12 @@ public:
|
||||
using shared_object = struct shared_object;
|
||||
using symbol = void*;
|
||||
|
||||
template<typename ctor>
|
||||
struct driver {
|
||||
int priority;
|
||||
ctor constructor;
|
||||
};
|
||||
|
||||
const string name;
|
||||
|
||||
virtual ~platform() = default;
|
||||
@@ -76,64 +83,35 @@ public:
|
||||
virtual void initialize(); // Initialize Drivers and Contexts
|
||||
virtual void shutdown(); // Close Drivers and Contexts
|
||||
|
||||
display* get_display() { return _display; }
|
||||
// Platform level functions for retrieving driver and protocol contexts ================================================
|
||||
|
||||
// Window Management
|
||||
using window_ctor = window* (*)(platform*, const window::config&);
|
||||
using window_driver = driver<window_ctor>;
|
||||
window* create_window(const window::config& config);
|
||||
static void register_window_driver(window_driver&& driver);
|
||||
|
||||
protected:
|
||||
template<typename PlatformT>
|
||||
explicit platform(const cstring& name, PlatformT* type)
|
||||
: typed(type)
|
||||
, name(name) {
|
||||
auto& globals = _get_globals();
|
||||
assertf(globals.singleton == nullptr, "Conflicting Platform Definitions.");
|
||||
globals.singleton = this;
|
||||
assertf(singleton == nullptr, "Conflicting platform implementations!");
|
||||
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;
|
||||
ctor constructor;
|
||||
};
|
||||
|
||||
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 platform* instance() {
|
||||
return singleton;
|
||||
}
|
||||
};
|
||||
|
||||
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();
|
||||
|
||||
public:
|
||||
static const global_context& get_globals() {
|
||||
return _get_globals();
|
||||
}
|
||||
|
||||
static platform* instance() {
|
||||
return _get_globals().singleton;
|
||||
}
|
||||
static platform* singleton;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -16,150 +16,127 @@
|
||||
// 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
|
||||
virtual ~window() = default;
|
||||
|
||||
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 {
|
||||
vsync_off = 0,
|
||||
vsync_on = 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 {
|
||||
uint8_t flags;
|
||||
display_mode mode;
|
||||
string title;
|
||||
uint32_t flags;
|
||||
size_t width, height;
|
||||
fullscreen_mode fullscreen;
|
||||
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;
|
||||
|
||||
virtual bool set_title(const cstring& title) = 0;
|
||||
virtual bool set_title(const string& title) = 0;
|
||||
bool is_fullscreen() const {
|
||||
return _config.flags & fullscreen;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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&) = 0;
|
||||
virtual void vsync(int8_t) = 0;
|
||||
virtual void set_progress(bool, float) = 0;
|
||||
|
||||
// Graphics ============================================================================================================
|
||||
|
||||
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 begin_frame() = 0;
|
||||
virtual void end_frame() = 0;
|
||||
|
||||
protected:
|
||||
template<typename TypeT>
|
||||
window(display* display, window* parent, TypeT* type)
|
||||
: typed(type)
|
||||
, _display(display)
|
||||
, _parent(parent)
|
||||
, _surface(nullptr) {
|
||||
}
|
||||
|
||||
display* _display;
|
||||
window* _parent;
|
||||
optional<config> _config;
|
||||
gfxsurface* _surface;
|
||||
config _config;
|
||||
|
||||
private:
|
||||
window(window* parent, const config& cfg)
|
||||
: _parent(parent)
|
||||
, _config(cfg) {
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
@@ -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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -16,22 +16,34 @@
|
||||
// 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
|
||||
///
|
||||
/// \file sdlwindow.h
|
||||
/// \brief
|
||||
///
|
||||
///
|
||||
/// \details
|
||||
/// \author Medusa Slockbower
|
||||
///
|
||||
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||
///
|
||||
///
|
||||
|
||||
#include <fennec/platform/interface/platform.h>
|
||||
#ifndef FENNEC_PLATFORM_SDL_SDLWINDOW_H
|
||||
#define FENNEC_PLATFORM_SDL_SDLWINDOW_H
|
||||
|
||||
#include <fennec/platform/interface/window.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace libwayland
|
||||
{
|
||||
class sdlwindow : public window {
|
||||
public:
|
||||
|
||||
bool load_symbols(platform* platform);
|
||||
void unload_symbols(platform* platform);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_DYN_H
|
||||
#endif // FENNEC_PLATFORM_SDL_SDLWINDOW_H
|
||||
@@ -17,7 +17,7 @@
|
||||
// =====================================================================================================================
|
||||
|
||||
///
|
||||
/// \file gfxsurface.h
|
||||
/// \file forward.h
|
||||
/// \brief
|
||||
///
|
||||
///
|
||||
@@ -28,49 +28,18 @@
|
||||
///
|
||||
///
|
||||
|
||||
#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>
|
||||
#ifndef FENNEC_RENDERERS_INTERFACE_FORWARD_H
|
||||
#define FENNEC_RENDERERS_INTERFACE_FORWARD_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()) {
|
||||
}
|
||||
};
|
||||
class renderer; // Overarching rendering scheme
|
||||
class gfxcontext; // Globals for an API's context
|
||||
class gfxresourcepool; // Handles resource creation, allocation, and mapping
|
||||
class gfxsubpass; // A subpass of the renderer, implements, for example, the steps of composing and lighting a deferred renderer
|
||||
class gfxpipeline; // A user-defined pipeline, e.g. the Vulkan pipeline needed to render the G-Buffer
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_PLATFORM_INTERFACE_GFXSURFACE_H
|
||||
#endif // FENNEC_RENDERERS_INTERFACE_FORWARD_H
|
||||
@@ -17,7 +17,7 @@
|
||||
// =====================================================================================================================
|
||||
|
||||
///
|
||||
/// \file surface.h
|
||||
/// \file gfxcontext.h
|
||||
/// \brief
|
||||
///
|
||||
///
|
||||
@@ -28,33 +28,31 @@
|
||||
///
|
||||
///
|
||||
|
||||
#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>
|
||||
#ifndef FENNEC_RENDERERS_INTERFACE_GFXCONTEXT_H
|
||||
#define FENNEC_RENDERERS_INTERFACE_GFXCONTEXT_H
|
||||
#include <fennec/renderers/interface/renderer.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
class eglsurface : public gfxsurface {
|
||||
class gfxcontext {
|
||||
public:
|
||||
~eglsurface() override;
|
||||
|
||||
void resize(size_t width, size_t height) override;
|
||||
gfxcontext& operator=(const gfxcontext&) = delete;
|
||||
gfxcontext& operator=(gfxcontext&&) = delete;
|
||||
|
||||
eglsurface(eglcontext* context, window* window);
|
||||
|
||||
EGLSurface get_egl_surface() {
|
||||
return _surface;
|
||||
renderer* get_renderer() {
|
||||
return _renderer;
|
||||
}
|
||||
|
||||
protected:
|
||||
renderer* _renderer;
|
||||
|
||||
gfxcontext(renderer* renderer);
|
||||
|
||||
private:
|
||||
void* _handle;
|
||||
EGLSurface _surface;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H
|
||||
#endif // FENNEC_RENDERERS_INTERFACE_GFXCONTEXT_H
|
||||
@@ -17,7 +17,7 @@
|
||||
// =====================================================================================================================
|
||||
|
||||
///
|
||||
/// \file fwd.h
|
||||
/// \file gfxsubpass.h
|
||||
/// \brief
|
||||
///
|
||||
///
|
||||
@@ -28,15 +28,14 @@
|
||||
///
|
||||
///
|
||||
|
||||
#ifndef FENNEC_PLATFORM_OPENGL_EGL_FWD_H
|
||||
#define FENNEC_PLATFORM_OPENGL_EGL_FWD_H
|
||||
#ifndef FENNEC_RENDERERS_INTERFACE_GFXSUBPASS_H
|
||||
#define FENNEC_RENDERERS_INTERFACE_GFXSUBPASS_H
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
class eglcontext;
|
||||
class eglsurface;
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_PLATFORM_OPENGL_EGL_FWD_H
|
||||
#endif // FENNEC_RENDERERS_INTERFACE_GFXSUBPASS_H
|
||||
@@ -16,47 +16,63 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
///
|
||||
/// \file gfxcontext.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_GFXCONTEXT_H
|
||||
#define FENNEC_PLATFORM_INTERFACE_GFXCONTEXT_H
|
||||
|
||||
#include <fennec/lang/types.h>
|
||||
#include <fennec/langproc/strings/string.h>
|
||||
#include <fennec/lang/typeuuid.h>
|
||||
#include <fennec/platform/interface/fwd.h>
|
||||
#include <fennec/platform/interface/window.h>
|
||||
#include <fennec/renderers/interface/forward.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
class gfxcontext : public typed<gfxcontext> {
|
||||
///
|
||||
/// \brief Defines a renderer interface to implement different graphics APIs, e.g. OpenGL Vulkan
|
||||
/// \details This represents the overarching renderer, and not any platform specific behaviour.
|
||||
/// I.E. This acts as a proxy for creating API objects, but the behaviour of those objects
|
||||
/// is defined elsewhere.
|
||||
class renderer {
|
||||
public:
|
||||
const string name;
|
||||
enum texture_ : uint8_t {
|
||||
texture_1d = 0,
|
||||
texture_1d_array,
|
||||
texture_2d,
|
||||
texture_2d_array,
|
||||
texture_multisample,
|
||||
texture_multisample_array,
|
||||
texture_cubemap,
|
||||
texture_cubemap_array,
|
||||
texture_3d,
|
||||
};
|
||||
|
||||
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;
|
||||
using handle_t = uint32_t;
|
||||
|
||||
virtual bool check_extension(const cstring& ext) = 0;
|
||||
virtual void make_current(gfxsurface* surface) = 0;
|
||||
struct version_t {
|
||||
uint8_t major, minor, patch;
|
||||
string str;
|
||||
};
|
||||
|
||||
virtual gfxsurface* create_surface(window* window) = 0;
|
||||
const version_t version;
|
||||
|
||||
virtual ~gfxcontext() = default;
|
||||
gfxcontext context;
|
||||
gfxresourcepool resources;
|
||||
|
||||
display* get_display() {
|
||||
return _display;
|
||||
}
|
||||
handle_t add_subpass();
|
||||
|
||||
protected:
|
||||
display* _display;
|
||||
private:
|
||||
|
||||
template<typename ContextT>
|
||||
gfxcontext(display* display, const cstring& name, ContextT* type)
|
||||
: typed(type)
|
||||
, name(name)
|
||||
, _display(display) {
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -61,16 +61,16 @@ enum access_ : GLbitfield {
|
||||
|
||||
enum texture_ : GLenum {
|
||||
TEX_1D = GL_TEXTURE_1D,
|
||||
TEX_1D_V = GL_TEXTURE_1D_ARRAY,
|
||||
TEX_1D_ARRAY = GL_TEXTURE_1D_ARRAY,
|
||||
|
||||
TEX_2D = GL_TEXTURE_2D,
|
||||
TEX_2D_V = GL_TEXTURE_2D_ARRAY,
|
||||
TEX_2D_ARRAY = GL_TEXTURE_2D_ARRAY,
|
||||
TEX_2D_MS = GL_TEXTURE_2D_MULTISAMPLE,
|
||||
TEX_2D_MS_V = GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
|
||||
TEX_2D_MS_ARRAY = GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
|
||||
TEX_RECT = GL_TEXTURE_RECTANGLE,
|
||||
|
||||
TEX_CUBEMAP = GL_TEXTURE_CUBE_MAP,
|
||||
TEX_CUBEMAP_V = GL_TEXTURE_CUBE_MAP_ARRAY,
|
||||
TEX_CUBEMAP_ARRAY = GL_TEXTURE_CUBE_MAP_ARRAY,
|
||||
|
||||
TEX_3D = GL_TEXTURE_3D,
|
||||
|
||||
@@ -57,14 +57,14 @@ namespace gl
|
||||
{
|
||||
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture1d = texture<TEX_1D, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture1dv = texture<TEX_1D_V, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture1d_array = texture<TEX_1D_ARRAY, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture2d = texture<TEX_2D, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture2dv = texture<TEX_2D_V, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture2d_array = texture<TEX_2D_ARRAY, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture_rect = texture<TEX_RECT, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture2d_ms = texture<TEX_2D_MS, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture2dv_ms = texture<TEX_2D_MS_V, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture2d_ms_array = texture<TEX_2D_MS_ARRAY, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using cubemap = texture<TEX_CUBEMAP, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using cubemapv = texture<TEX_CUBEMAP_V, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using cubemap_array = texture<TEX_CUBEMAP_ARRAY, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture3d = texture<TEX_3D, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using buffer_texture = texture<TEX_BUFFER, FormatV, ImmutableV>;
|
||||
|
||||
@@ -87,17 +87,17 @@ public:
|
||||
static constexpr GLboolean immutable = ImmutableV;
|
||||
static constexpr GLboolean is_rect = type == TEX_RECT;
|
||||
static constexpr GLboolean is_buffered = type == TEX_BUFFER;
|
||||
static constexpr GLboolean sampled = type == TEX_2D_MS or type == TEX_2D_MS_V;
|
||||
static constexpr GLboolean cubemap = type == TEX_CUBEMAP or type == TEX_CUBEMAP_V;
|
||||
static constexpr GLboolean is_1d = type == TEX_1D or type == TEX_1D_V;
|
||||
static constexpr GLboolean is_2d = sampled or is_rect or type == TEX_2D or type == TEX_2D_V or cubemap;
|
||||
static constexpr GLboolean is_array = TypeV == TEX_1D_V or TypeV == TEX_2D_V or type == TEX_2D_MS_V or type == TEX_CUBEMAP_V;
|
||||
static constexpr GLboolean sampled = type == TEX_2D_MS or type == TEX_2D_MS_ARRAY;
|
||||
static constexpr GLboolean cubemap = type == TEX_CUBEMAP or type == TEX_CUBEMAP_ARRAY;
|
||||
static constexpr GLboolean is_1d = type == TEX_1D or type == TEX_1D_ARRAY;
|
||||
static constexpr GLboolean is_2d = sampled or is_rect or type == TEX_2D or type == TEX_2D_ARRAY or cubemap;
|
||||
static constexpr GLboolean is_array = TypeV == TEX_1D_ARRAY or TypeV == TEX_2D_ARRAY or type == TEX_2D_MS_ARRAY or type == TEX_CUBEMAP_ARRAY;
|
||||
static constexpr GLboolean is_3d = TypeV == TEX_3D;
|
||||
static constexpr GLboolean has_mipmaps = not(sampled or is_rect or is_buffered);
|
||||
|
||||
static constexpr GLboolean use_1d = is_1d and not is_array;
|
||||
static constexpr GLboolean use_2d = (is_2d and not is_array) or (is_1d and is_array) and not sampled;
|
||||
static constexpr GLboolean use_3d = is_3d or (is_2d and is_array) and not sampled and not cubemap;
|
||||
static constexpr GLboolean use_2d = ((is_2d and not is_array) or (is_1d and is_array)) and not sampled;
|
||||
static constexpr GLboolean use_3d = (is_3d or (is_2d and is_array)) and not (sampled or cubemap);
|
||||
|
||||
static constexpr GLint cubemap_faces = 6;
|
||||
static constexpr GLenum base_cubemap_face = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <fennec/containers/map.h>
|
||||
#include <fennec/containers/optional.h>
|
||||
#include <fennec/langproc/strings/string.h>
|
||||
#include <fennec/lang/typeuuid.h>
|
||||
#include <fennec/lang/typed.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
|
||||
<!-- I release these notes into the public domain -->
|
||||
|
||||
# 2D Graphics (`gfx2d`)
|
||||
|
||||
## Table of Contents
|
||||
@@ -27,6 +29,11 @@ For the 2d rendering framework, Materials need to be rendered independently beca
|
||||
no size constraints for images. This disallows us from using a meta-shader like in
|
||||
the 3d rendering framework.
|
||||
|
||||
I may have come up with a solution for the above problem. We can define software
|
||||
subsections for images that are of differing size, then fit them to the optimal
|
||||
texture array size. The textures will be centered in the storage, then have padding
|
||||
that fits one of the wrapping models supported by samplers
|
||||
|
||||
```c++
|
||||
struct Object
|
||||
{
|
||||
@@ -62,3 +69,4 @@ struct Object
|
||||
- Translucent objects will be sorted. We can cheat by using a z-index instead of a z-coordinate.
|
||||
This will allow us to sort objects as they are created. We can still bulk render each z-index,
|
||||
with meshes and objects being grouped by material.
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
|
||||
<!-- I release these notes into the public domain -->
|
||||
|
||||
# 3D Graphics (`gfx3d`)
|
||||
|
||||
## Table of Contents
|
||||
@@ -67,8 +69,8 @@ Objects are identified with a manually provided type and ID. Object types includ
|
||||
A user should never have to specify these and should be automatically generated by the respective components.
|
||||
|
||||
Textures for 3D rendering are stored in various buffers with sizes of powers of 2. Ratios of `1:1`
|
||||
and `2:1` are allowed. The `2:1` ratio is specifically for spherical and cylindrical projection. UVs
|
||||
may be transformed to use a `2:1` as if it were `1:2`.
|
||||
`2:1`, and `4:1` are allowed. The `2:1` ratio is specifically for spherical and cylindrical projection. UVs
|
||||
may be transformed to use a `2:1` as if it were `1:2`. Same applies for `4:1`
|
||||
Cubemaps and 3D textures may only be `1:1`.
|
||||
|
||||
- 8-Bit R Texture `4096, 2048, 1024, 512` (8)
|
||||
@@ -170,12 +172,12 @@ Debug View: Visibility Buffer
|
||||
* S → used to represent the lighting model.
|
||||
* Diffuse → `RGBA8`
|
||||
* A → Ambient Occlusion
|
||||
* Emission → `RGB8`
|
||||
* Normal → `RGB8`
|
||||
* Specular → `RGB8`
|
||||
* R → Roughness
|
||||
* G → Specularity (sometimes called the Metallicness)
|
||||
* G → Specularity (sometimes called the Metallicity)
|
||||
* B → Index of Refraction (IOR)
|
||||
* Emission → `RGB8`
|
||||
* Normal → `RGB8`
|
||||
|
||||
Debug View: Depth, Stencil, Diffuse, Emission, Normal, Specularity
|
||||
|
||||
@@ -195,9 +197,9 @@ We can combine all of these into one framebuffer:
|
||||
- Depth - Stencil → `D24_S8`
|
||||
- Visibility Info → `RGB32I`
|
||||
- Diffuse → `RGBA8`
|
||||
- Specular → `RGB8`
|
||||
- Emission → `RGB8`
|
||||
- Normal → `RGB8`
|
||||
- Specular → `RGB8`
|
||||
- Lighting Buffer → `RGB16` w/ Mipmapping
|
||||
- One more slot left open for another
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
|
||||
<!-- I release these notes into the public domain -->
|
||||
|
||||
# 3D Physics (`physics3d`)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
|
||||
<!-- I release these notes into the public domain -->
|
||||
|
||||
# Artifical Intelligence (`ai`)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
|
||||
<!-- I release these notes into the public domain -->
|
||||
|
||||
# Containers Library (`containers`)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
|
||||
<!-- I release these notes into the public domain -->
|
||||
|
||||
# Planning Documentation for fennec
|
||||
|
||||
## Table of Contents
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
|
||||
<!-- I release these notes into the public domain -->
|
||||
|
||||
# C++ Language Library (`lang`)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
BIN
planning/ControlScene.ods
Normal file
BIN
planning/ControlScene.ods
Normal file
Binary file not shown.
@@ -1,4 +1,6 @@
|
||||
|
||||
<!-- I release these notes into the public domain -->
|
||||
|
||||
# fennec
|
||||
|
||||
## Table of Contents
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
|
||||
<!-- I release these notes into the public domain -->
|
||||
|
||||
# Language Processing Library (`langproc`)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
|
||||
<!-- I release these notes into the public domain -->
|
||||
|
||||
# Memory Library (`memory`)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
|
||||
<!-- I release these notes into the public domain -->
|
||||
|
||||
# Platform Support Library (`platform`)
|
||||
|
||||
## Table of Contents
|
||||
@@ -20,6 +22,14 @@ to supporting various platforms. Platforms may be defined as any Hardware, OS, o
|
||||
Drivers that must be initialized for the engine context.
|
||||
|
||||
|
||||
## Changes
|
||||
|
||||
  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:
|
||||
@@ -59,3 +69,56 @@ then support for other platforms will be resumed.
|
||||
with the principles of this engine. fennec will avoid using proprietary libraries except
|
||||
when strictly necessary, such as support for Windows and MacOS. fennec will interact
|
||||
with any drivers required for the listed operating systems above, even if proprietary.
|
||||
|
||||
## Notes
|
||||
|
||||
We want this system to be fairly modular, renderers and their respective
|
||||
gfxcontext implementation should be a drop-in, as well as window implementation.
|
||||
This is a fairly complex problem to solve, especially since most display protocols
|
||||
have their own specific implementation for supporting different contexts.
|
||||
|
||||
To illustrate this problem, let's say we have SDL and OpenGL implemented.
|
||||
|
||||
If we were to add Vulkan, there are Vulkan specific functions
|
||||
for creating a window compatible with SDL, i.e. SDL_Vulkan_CreateSurface.
|
||||
Who should know how to implement this function? How do we define the API
|
||||
so that we do not have to modify existing classes to add Vulkan support?
|
||||
|
||||
The easiest solution to this problem is template functions. We can have a
|
||||
template that takes a Renderer type as a template parameter, then initialize
|
||||
the window for that. Now, if someone wants to create a Vulkan renderer, all they
|
||||
have to do is write an overload for the template function. This can be neatly
|
||||
wrapped up in a single C++ file. Only the gfxcontext implementation has to know
|
||||
of this function's existence since it will be the one calling the function.
|
||||
|
||||
The main drawback with this implementation is an outside observer calling the
|
||||
template function directly. Only the one C++ file knows of its existence. Template
|
||||
functions are inlined after all. There are two options to solve this, the ``[[noinline]]``
|
||||
attribute, or we simply scope protect the function and create it purely from a
|
||||
"driver" standpoint. We can register drivers with the platform, then retrieve a
|
||||
list of drivers with a specific type, e.g. glcontext, then the type aware implementation
|
||||
is isolated to the C++ file associated with glcontext, and glcontext registers
|
||||
itself with the platform. We can give drivers a priority so that Vulkan, a more
|
||||
modern and "more powerful" renderer is chosen first, if available, and falls back
|
||||
to OpenGL.
|
||||
|
||||
Now we run into the issue of, what if we want to implement Vulkan and Wayland separately?
|
||||
These implementations will be part of the core engine, but let's take a more contrived
|
||||
example; X-Box and Playstation. X-Box and Playstation have their own protocols for
|
||||
display rendering, but both use DirectX. Say someone implements a DirectX api for Desktop
|
||||
computers, then someone else implements a windowing system for X-Box or Playstation.
|
||||
If another user wants to use DirectX with X-Box/Playstation, they will have to write
|
||||
their own overloads for that implementation.
|
||||
|
||||
The only viable solution for this problem is to rely on the Open Source community.
|
||||
Pray that someone finds both engine extensions and writes the overloads for you.
|
||||
This might sound very familiar to modders, and this is my intention with this engine.
|
||||
Pieces should be modular, and should be easily connected when two non-dependent systems
|
||||
have underlying interdependencies.
|
||||
|
||||
There is one more option that I have come up with; mapping type ids. The implementation
|
||||
of typed.h generates type ids *at runtime* which allows us to map a pair of ids for this
|
||||
purpose. We can use a pair of window and gfxcontext uuids to determine the loading functions.
|
||||
All we would need to do is register a function that takes a window as an arguments and
|
||||
constructs the gfxcontext. We can combine this with the above to allow scoped access to
|
||||
the classes if that is needed.
|
||||
|
||||
26
planning/RENDERERS.md
Normal file
26
planning/RENDERERS.md
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
<!-- I release these notes into the public domain -->
|
||||
|
||||
# Renderers (`renderers`)
|
||||
|
||||
|
||||
|
||||
|
||||
## Introduction
|
||||
|
||||
  This library contains headers and classes related to creating renderers
|
||||
that wrap various graphics pipelines, e.g. OpenGL & Vulkan.
|
||||
|
||||
|
||||
## Implementation
|
||||
|
||||
OpenGL will be implemented first for prototyping, then Vulkan will
|
||||
be implemented. These will be the first two renderers with official
|
||||
support. OpenGL will be implemented twice, one targeting modern features,
|
||||
and a fallback targeting OpenGL 4.3 / GLES 3.2.
|
||||
|
||||
OpenGL will be wrapped in a manner that reflects the Vulkan API. This
|
||||
will help achieve higher performance with driver usage in OpenGL, and
|
||||
it will make building pipelines on top of OpenGL easier. This will also
|
||||
give the advantage of a cleaner porting process when writing the Vulkan
|
||||
pipeline.
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,42 +36,13 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
window* platform::create_window(const window::config& config) {
|
||||
|
||||
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() {
|
||||
static global_context ctx;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,11 +29,9 @@ STATIC_CONSTRUCTOR(_init_linux) {
|
||||
}
|
||||
|
||||
void linux_platform::initialize() {
|
||||
platform::initialize();
|
||||
}
|
||||
|
||||
void linux_platform::shutdown() {
|
||||
platform::shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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!"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user