Compare commits

..

8 Commits

Author SHA1 Message Date
086c73f058 Merge branch 'main' of https://git.mslockbo.org/mslockbo/fennec
Messed up some files and git wants to merge
2025-08-22 12:03:26 -04:00
339f5c8cd8 - Added XDG Shell 2025-08-22 12:03:04 -04:00
18c0a7099d - Comment noting an error with stdint isinf and isnan 2025-08-22 03:03:54 -04:00
540c7fbce8 - Similar refactor on XKB 2025-08-22 02:53:09 -04:00
cbcd699ab0 - Decided to remove boost due to extensive dependencies
- Huge refactor on Wayland loading to support retrieval of Protocol headers
 - Setup EGL to create surfaces for Wayland windows
2025-08-22 02:15:57 -04:00
ff27caab4f - Fixed some variable naming with graph and it's PrettyPrinter
- Added boost-atomic and boost-thread as dependencies for concurrency support
2025-08-21 06:44:22 -04:00
fe4c49d092 - Fixed several memory errors 2025-08-20 20:57:15 -04:00
037c62bf12 - Added missing functionality from C++ spec 2025-08-20 14:00:52 -04:00
84 changed files with 15814 additions and 6917 deletions

View File

@@ -20,14 +20,29 @@ cmake_minimum_required(VERSION 3.30)
project(fennec) project(fennec)
# External dependencies should be loaded here # External dependencies should be loaded here
# CppTrace is a dependency of the project, added as a git submodule
add_subdirectory(external/cpptrace) add_subdirectory(external/cpptrace)
set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD 23)
set(CMAKE_C_STANDARD 23) set(CMAKE_C_STANDARD 23)
set(FENNEC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) 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()
macro(fennec_add_definitions)
list(APPEND FENNEC_COMPILE_DEFINITIONS ${ARGN})
endmacro()
macro(fennec_add_link_libraries)
list(APPEND FENNEC_LINK_LIBRARIES ${ARGN})
endmacro()
# include scripts # include scripts
include("${FENNEC_SOURCE_DIR}/cmake/version.cmake") include("${FENNEC_SOURCE_DIR}/cmake/version.cmake")
include("${FENNEC_SOURCE_DIR}/cmake/platform.cmake") include("${FENNEC_SOURCE_DIR}/cmake/platform.cmake")
@@ -85,6 +100,7 @@ add_library(fennec STATIC
include/fennec/containers/set.h include/fennec/containers/set.h
include/fennec/containers/traversal.h include/fennec/containers/traversal.h
include/fennec/containers/tuple.h include/fennec/containers/tuple.h
include/fennec/containers/variant.h
include/fennec/containers/detail/_tuple.h include/fennec/containers/detail/_tuple.h
@@ -138,11 +154,6 @@ add_library(fennec STATIC
include/fennec/memory/detail/_ptr_traits.h include/fennec/memory/detail/_ptr_traits.h
# CONCURRENCY ==========================================================================================================
include/fennec/concurrency/thread.h
include/fennec/concurrency/mutex.h
include/fennec/concurrency/atomic.h
# DEBUG ================================================================================================================ # DEBUG ================================================================================================================
source/debug/assert_impl.cpp source/debug/assert_impl.cpp
@@ -203,6 +214,7 @@ add_library(fennec STATIC
include/fennec/platform/interface/platform.h source/platform/interface/platform.cpp 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/display.h source/platform/interface/display.cpp
include/fennec/platform/interface/gfxcontext.h include/fennec/platform/interface/gfxcontext.h
include/fennec/platform/interface/gfxsurface.h
# EXTRA SOURCES ======================================================================================================== # EXTRA SOURCES ========================================================================================================
@@ -210,7 +222,7 @@ add_library(fennec STATIC
${FENNEC_EXTRA_SOURCES} ${FENNEC_EXTRA_SOURCES}
) )
add_dependencies(fennec metaprogramming) add_dependencies(fennec metaprogramming fennec-dependencies)
target_compile_definitions(fennec PUBLIC target_compile_definitions(fennec PUBLIC
${FENNEC_COMPILE_DEFINITIONS} ${FENNEC_COMPILE_DEFINITIONS}
@@ -222,8 +234,9 @@ target_link_options(fennec PRIVATE ${FENNEC_PRIVATE_LINK_OPTIONS}) # Do not comp
# This implementation is designed to be as readable as possible, and expose information that would otherwise be obfuscated # This implementation is designed to be as readable as possible, and expose information that would otherwise be obfuscated
target_link_libraries(fennec PRIVATE target_link_libraries(fennec PRIVATE
cpptrace::cpptrace
${FENNEC_LINK_LIBRARIES} ${FENNEC_LINK_LIBRARIES}
cpptrace::cpptrace
) )

View File

@@ -3,7 +3,7 @@
# Readings # Readings
Here is a list of relevant books and articles on various concepts related to Here is a list of relevant books and articles on various concepts related to
developing a game engine and its subsystems. developing a game engine and its subsystems.
- Game Engine Architecture, Ed. 3 – Jason Gregory - Game Engine Architecture, Ed. 3 – Jason Gregory

View File

@@ -90,7 +90,7 @@ fennec Standards:
immediate events to listeners so that outside functionality may decide how to handle the impending crash. immediate events to listeners so that outside functionality may decide how to handle the impending crash.
In Debug Mode there is nothing that can be done to stop the crash, as soon as the branch finishes, In Debug Mode there is nothing that can be done to stop the crash, as soon as the branch finishes,
`abort()` will be called. `abort()` will be called.
<br> <br>

View File

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

View File

@@ -23,13 +23,13 @@ macro(fennec_check_platform)
include("${FENNEC_SOURCE_DIR}/cmake/unix.cmake") include("${FENNEC_SOURCE_DIR}/cmake/unix.cmake")
# compile definitions # compile definitions
list(APPEND FENNEC_COMPILE_DEFINITIONS fennec_add_definitions(
FENNEC_PLATFORM_NAME="Linux" FENNEC_PLATFORM_NAME="Linux"
FENNEC_PLATFORM_LINUX=1 FENNEC_PLATFORM_LINUX=1
) )
# extra source files # extra source files
list(APPEND FENNEC_EXTRA_SOURCES fennec_add_sources(
include/fennec/platform/linux/platform.h source/platform/linux/platform.cpp include/fennec/platform/linux/platform.h source/platform/linux/platform.cpp
) )

View File

@@ -27,8 +27,8 @@ endif()
if(TARGET OpenGL::GL AND TARGET GLEW::GLEW) if(TARGET OpenGL::GL AND TARGET GLEW::GLEW)
message(STATUS "Found OpenGL: ${OPENGL_gl_LIBRARY}") message(STATUS "Found OpenGL: ${OPENGL_gl_LIBRARY}")
list(APPEND FENNEC_LINK_LIBRARIES OpenGL::GL GLEW::GLEW) fennec_add_link_libraries(OpenGL::GL GLEW::GLEW)
list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_GRAPHICS_OPENGL=1) fennec_add_definitions(FENNEC_GRAPHICS_OPENGL=1)
else() else()
message(FATAL_ERROR "No Suitable OpenGL implementation found.") message(FATAL_ERROR "No Suitable OpenGL implementation found.")
endif() endif()
@@ -39,15 +39,19 @@ if(FENNEC_GRAPHICS_WANT_EGL)
endif() endif()
message(STATUS "Found EGL: ${OPENGL_egl_LIBRARY}") message(STATUS "Found EGL: ${OPENGL_egl_LIBRARY}")
list(APPEND FENNEC_LINK_LIBRARIES OpenGL::EGL)
list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_GRAPHICS_EGL=1) fennec_add_link_libraries(OpenGL::EGL)
list(APPEND FENNEC_EXTRA_SOURCES fennec_add_definitions(FENNEC_GRAPHICS_EGL=1)
fennec_add_sources(
include/fennec/platform/opengl/lib/fwd.h include/fennec/platform/opengl/lib/fwd.h
include/fennec/platform/opengl/lib/enum.h include/fennec/platform/opengl/lib/enum.h
include/fennec/platform/opengl/lib/buffer.h include/fennec/platform/opengl/lib/buffer.h
include/fennec/platform/opengl/lib/texture.h include/fennec/platform/opengl/lib/texture.h
include/fennec/platform/opengl/lib/vertex_array.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/context.h source/platform/opengl/egl/context.cpp
include/fennec/platform/opengl/egl/surface.h source/platform/opengl/egl/surface.cpp
) )
endif() endif()

View File

@@ -19,11 +19,11 @@
# generic unix functionality # generic unix functionality
# compile definitions # compile definitions
list(APPEND FENNEC_COMPILE_DEFINITIONS fennec_add_definitions(
FENNEC_PLATFORM_UNIX=1 FENNEC_PLATFORM_UNIX=1
) )
# extra source files # extra source files
list(APPEND FENNEC_EXTRA_SOURCES fennec_add_sources(
include/fennec/platform/unix/platform.h source/platform/unix/platform.cpp include/fennec/platform/unix/platform.h source/platform/unix/platform.cpp
) )

View File

@@ -19,6 +19,23 @@
# https://gist.github.com/mariobadr/acc3c8adf4b4e722705be38c3deac59a # https://gist.github.com/mariobadr/acc3c8adf4b4e722705be38c3deac59a
# this script finds libwayland and dependencies # 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) macro(fennec_check_wayland)
set(WAYLAND_CLIENT_FOUND 0) set(WAYLAND_CLIENT_FOUND 0)
@@ -30,6 +47,7 @@ macro(fennec_check_wayland)
WAYLAND_CLIENT_LIBRARY WAYLAND_CLIENT_LIBRARY
NAMES wayland-client libwayland-client NAMES wayland-client libwayland-client
) )
find_program(WAYLAND_SCANNER NAMES wayland-scanner)
# EGL is required # EGL is required
find_path( find_path(
@@ -41,13 +59,34 @@ macro(fennec_check_wayland)
NAMES wayland-egl libwayland-egl NAMES wayland-egl libwayland-egl
) )
if( (WAYLAND_CLIENT_INCLUDE_DIR AND WAYLAND_CLIENT_LIBRARY) if( (WAYLAND_CLIENT_INCLUDE_DIR AND WAYLAND_CLIENT_LIBRARY AND WAYLAND_SCANNER)
AND (WAYLAND_EGL_INCLUDE_DIR AND WAYLAND_EGL_LIBRARY)) AND (WAYLAND_EGL_INCLUDE_DIR AND WAYLAND_EGL_LIBRARY))
message(STATUS "Found Wayland: ${WAYLAND_CLIENT_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") include("${FENNEC_SOURCE_DIR}/cmake/xkb.cmake")
fennec_check_xkb() 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( get_filename_component(
WAYLAND_CLIENT_LIBRARY WAYLAND_CLIENT_LIBRARY
${WAYLAND_CLIENT_LIBRARY} ${WAYLAND_CLIENT_LIBRARY}
@@ -63,19 +102,18 @@ macro(fennec_check_wayland)
set(WAYLAND_EGL_FOUND 1) set(WAYLAND_EGL_FOUND 1)
set(FENNEC_GRAPHICS_WANT_EGL 1) set(FENNEC_GRAPHICS_WANT_EGL 1)
list(APPEND FENNEC_EXTRA_SOURCES fennec_add_sources(
# Dynamic Library Files # Dynamic Library Files
include/fennec/platform/linux/wayland/lib/fwd.h
include/fennec/platform/linux/wayland/lib/sym.h include/fennec/platform/linux/wayland/lib/sym.h
include/fennec/platform/linux/wayland/lib/wayland-client.h include/fennec/platform/linux/wayland/lib/wayland.h
include/fennec/platform/linux/wayland/lib/wayland-util.h
include/fennec/platform/linux/wayland/lib/loader.h source/platform/linux/wayland/lib/loader.cpp include/fennec/platform/linux/wayland/lib/loader.h source/platform/linux/wayland/lib/loader.cpp
# Fennec Files # Fennec Files
include/fennec/platform/linux/wayland/display.h source/platform/linux/wayland/display.cpp 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
) )
list(APPEND FENNEC_COMPILE_DEFINITIONS fennec_add_definitions(
FENNEC_HAS_WAYLAND=1 FENNEC_HAS_WAYLAND=1
FENNEC_LIB_WAYLAND="${WAYLAND_CLIENT_LIBRARY}" FENNEC_LIB_WAYLAND="${WAYLAND_CLIENT_LIBRARY}"
FENNEC_LIB_WAYLAND_EGL="${WAYLAND_EGL_LIBRARY}" FENNEC_LIB_WAYLAND_EGL="${WAYLAND_EGL_LIBRARY}"

View File

@@ -41,17 +41,16 @@ macro(fennec_check_xkb)
set(XKB_FOUND 1) set(XKB_FOUND 1)
list(APPEND FENNEC_EXTRA_SOURCES fennec_add_sources(
# Dynamic Library Files # Dynamic Library Files
include/fennec/platform/linux/xkb/lib/fwd.h
include/fennec/platform/linux/xkb/lib/sym.h include/fennec/platform/linux/xkb/lib/sym.h
include/fennec/platform/linux/xkb/lib/xkbcommon.h include/fennec/platform/linux/xkb/lib/xkb.h
include/fennec/platform/linux/xkb/lib/loader.h source/platform/linux/xkb/lib/loader.cpp include/fennec/platform/linux/xkb/lib/loader.h source/platform/linux/xkb/lib/loader.cpp
# Fennec files # Fennec files
) )
list(APPEND FENNEC_COMPILE_DEFINITIONS fennec_add_definitions(
FENNEC_HAS_XKB=1 FENNEC_HAS_XKB=1
FENNEC_LIB_XKB="${XKB_LIBRARY}" FENNEC_LIB_XKB="${XKB_LIBRARY}"
) )

View File

@@ -396,10 +396,10 @@ class GraphPrinter:
class Iterator: class Iterator:
def __init__(self, val): def __init__(self, val):
self.node_pool = val['_node_pool']['_table']['_alloc']['_data'] self.node_pool = val['_vertex_pool']['_table']['_alloc']['_data']
self.max_nodes = val['_node_pool']['_table']['_alloc']['_capacity'] self.max_nodes = val['_vertex_pool']['_table']['_alloc']['_capacity']
self.conn_map = val['_conn_map']['_alloc']['_data'] self.conn_map = val['_edge_map']['_alloc']['_data']
self.max_conn = val['_conn_map']['_size'] self.max_conn = val['_edge_map']['_size']
self.index = 0 self.index = 0
def __iter__(self): def __iter__(self):
@@ -447,7 +447,7 @@ class GraphPrinter:
def __init__(self, val): def __init__(self, val):
self.val = val self.val = val
self.size = val['_node_pool']['_size'] self.size = val['_vertex_pool']['_size']
def to_string(self): def to_string(self):
if self.size == 0: if self.size == 0:

View File

@@ -27,7 +27,7 @@ class CStringPrinter:
return 'string' return 'string'
def to_string(self): def to_string(self):
value = "\"" + self.val['_str'].string('', 'replace', self.val['_size'] - 1) + "\"" value = "\"" + self.val['_str'].string('', 'replace', self.val['_size']) + "\""
return value return value
def display_hint(self): def display_hint(self):

View File

@@ -60,8 +60,12 @@ namespace fennec
/// \tparam ValueT value type /// \tparam ValueT value type
/// \tparam ElemV number of elements /// \tparam ElemV number of elements
template<typename ValueT, size_t ElemV> template<typename ValueT, size_t ElemV>
struct array struct array {
{
// Definitions =========================================================================================================
public:
using value_t = ValueT; ///< Alias for `ValueT`
// Public Members ====================================================================================================== // Public Members ======================================================================================================
/// \name Public Members /// \name Public Members
@@ -69,7 +73,7 @@ struct array
/// ///
/// \brief backing c-style array handle /// \brief backing c-style array handle
ValueT elements[ElemV]; value_t data[ElemV];
/// @} /// @}
@@ -101,9 +105,9 @@ struct array
/// ///
/// \copydetails array::operator[](size_t) const /// \copydetails array::operator[](size_t) const
constexpr ValueT& operator[](size_t i) { constexpr value_t& operator[](size_t i) {
assertd(i < ElemV, "Array Out of Bounds"); assertd(i < ElemV, "Array Out of Bounds");
return elements[i]; return data[i];
} }
/// ///
@@ -117,9 +121,37 @@ struct array
/// ///
/// \par Space-Complexity /// \par Space-Complexity
/// Constant /// Constant
constexpr const ValueT& operator[](size_t i) const { constexpr const value_t& operator[](size_t i) const {
assertd(i < ElemV, "Array Out of Bounds"); assertd(i < ElemV, "Array Out of Bounds");
return elements[i]; return data[i];
}
///
/// \brief Access the first element
/// \returns A reference to the element at `elements[0]`
constexpr value_t& front() {
return data[0];
}
///
/// \brief Const Access the first element
/// \returns A const-qualified reference to the element at `elements[0]`
constexpr const value_t& front() const {
return data[0];
}
///
/// \brief Access the first element
/// \returns A reference to the element at `elements[ElemV - 1]`
constexpr value_t& back() {
return data[ElemV - 1];
}
///
/// \brief Const Access the first element
/// \returns A const-qualified reference to the element at `elements[ElemV - 1]`
constexpr const value_t& back() const {
return data[ElemV - 1];
} }
/// @} /// @}
@@ -154,15 +186,15 @@ struct array
/// ///
/// \brief C++ Iterator Specification `begin()` /// \brief C++ Iterator Specification `begin()`
/// \returns A pointer to the first element of the array /// \returns A pointer to the first element of the array
constexpr ValueT* begin() { constexpr value_t* begin() {
return elements; return data;
} }
/// ///
/// \brief C++ Iterator Specification `end()` /// \brief C++ Iterator Specification `end()`
/// \returns A pointer to one after the end of the array /// \returns A pointer to one after the end of the array
constexpr ValueT* end() { constexpr value_t* end() {
return elements + ElemV; return data + ElemV;
} }
@@ -170,15 +202,15 @@ struct array
/// ///
/// \brief Const C++ Iterator Specification `begin()` /// \brief Const C++ Iterator Specification `begin()`
/// \returns A const-qualified pointer to the first element of the array /// \returns A const-qualified pointer to the first element of the array
constexpr const ValueT* begin() const { constexpr const value_t* begin() const {
return elements; return data;
} }
/// ///
/// \brief Const C++ Iterator Specification `end()` /// \brief Const C++ Iterator Specification `end()`
/// \returns A const-qualified pointer to one after the end of the array /// \returns A const-qualified pointer to one after the end of the array
constexpr const ValueT* end() const { constexpr const value_t* end() const {
return elements + ElemV; return data + ElemV;
} }
/// @} /// @}

View File

@@ -102,6 +102,16 @@ public:
, _size(0) { , _size(0) {
} }
///
/// \brief Alloc Constructor, initializes an empty deque with the specified allocator
/// \param alloc the allocator to copy
deque(const alloc_t& alloc)
: _alloc(alloc)
, _first(nullptr)
, _last(nullptr)
, _size(0) {
}
/// ///
/// \brief Copy Constructor /// \brief Copy Constructor
/// \param deque the deque to copy /// \param deque the deque to copy

View File

@@ -29,9 +29,12 @@ template <std::size_t I, typename T>
struct _tuple_leaf struct _tuple_leaf
{ {
template <typename ArgT> template <typename ArgT>
_tuple_leaf(ArgT&& arg) : value(fennec::forward<ArgT>(arg)) {} constexpr _tuple_leaf(ArgT&& arg) : value(fennec::forward<ArgT>(arg)) {}
~_tuple_leaf() = default; constexpr ~_tuple_leaf() = default;
constexpr _tuple_leaf& operator=(const _tuple_leaf&) = default;
constexpr _tuple_leaf& operator=(_tuple_leaf&&) noexcept = default;
T value; T value;
}; };
@@ -43,9 +46,14 @@ template <size_t...IndicesV, typename...TypesT>
struct _tuple<const_index_sequence<IndicesV...>, TypesT...> : _tuple_leaf<IndicesV, TypesT>... struct _tuple<const_index_sequence<IndicesV...>, TypesT...> : _tuple_leaf<IndicesV, TypesT>...
{ {
template <typename...ArgsT> template <typename...ArgsT>
_tuple(ArgsT&&... args) : _tuple_leaf<IndicesV, TypesT>(fennec::forward<ArgsT>(args))... {} constexpr _tuple(ArgsT&&... args)
: _tuple_leaf<IndicesV, TypesT>(fennec::forward<ArgsT>(args))... {
}
~_tuple() = default; constexpr _tuple& operator=(const _tuple&) = default;
constexpr _tuple& operator=(_tuple&&) noexcept = default;
constexpr ~_tuple() = default;
}; };
} }

View File

@@ -149,7 +149,7 @@ public:
/// ///
/// \returns The number of edges in the graph /// \returns The number of edges in the graph
constexpr size_t num_edges() const { constexpr size_t num_edges() const {
return _conn_pool.size(); return _edge_pool.size();
} }
/// ///
@@ -170,7 +170,7 @@ public:
/// \param b The second vertex /// \param b The second vertex
/// \returns `true` if the edge exists, `false` otherwise /// \returns `true` if the edge exists, `false` otherwise
constexpr bool exists(size_t a, size_t b) const { constexpr bool exists(size_t a, size_t b) const {
return _conn_map[a][b] != nullptr; return _edge_map[a][b] != nullptr;
} }
/// ///
@@ -189,8 +189,8 @@ public:
/// \param b The second vertex /// \param b The second vertex
/// \returns `true` if both edges exist, `false` otherwise /// \returns `true` if both edges exist, `false` otherwise
constexpr bool is_undirected(size_t a, size_t b) const { constexpr bool is_undirected(size_t a, size_t b) const {
const auto* e0 = _conn_map[a][b]; const auto* e0 = _edge_map[a][b];
const auto* e1 = _conn_map[b][a]; const auto* e1 = _edge_map[b][a];
if (not (e0 != nullptr && e1 != nullptr)) { if (not (e0 != nullptr && e1 != nullptr)) {
return false; return false;
} }
@@ -232,9 +232,9 @@ public:
if (empty()) { if (empty()) {
return nullptr; return nullptr;
} }
edge_t* it = _conn_map[a][b]; edge_t* it = _edge_map[a][b];
if (it) { if (it) {
return _conn_pool[*it]; return _edge_pool[*it];
} }
return nullptr; return nullptr;
} }
@@ -248,9 +248,9 @@ public:
if (empty()) { if (empty()) {
return nullptr; return nullptr;
} }
const edge_t* it = _conn_map[a][b]; const edge_t* it = _edge_map[a][b];
if (it) { if (it) {
return _conn_pool[*it]; return _edge_pool[*it];
} }
return nullptr; return nullptr;
} }
@@ -261,10 +261,10 @@ public:
/// \returns A list containing all vertices `x` with edges from `vertex` to `x...` /// \returns A list containing all vertices `x` with edges from `vertex` to `x...`
list<size_t> outgoing(size_t vertex) { list<size_t> outgoing(size_t vertex) {
list<size_t> res; list<size_t> res;
if (empty() || vertex >= _conn_map.size()) { if (empty() || vertex >= _edge_map.size()) {
return res; return res;
} }
for (const auto& it : _conn_map[vertex]) { for (const auto& it : _edge_map[vertex]) {
res.push_back(it.first); res.push_back(it.first);
} }
return res; return res;
@@ -276,11 +276,11 @@ public:
/// \returns A list containing all vertices `x` with edges from `x...` to `vertex` /// \returns A list containing all vertices `x` with edges from `x...` to `vertex`
list<size_t> incoming(size_t vertex) { list<size_t> incoming(size_t vertex) {
list<size_t> res; list<size_t> res;
if (empty() || vertex >= _conn_map.size()) { if (empty() || vertex >= _edge_map.size()) {
return res; return res;
} }
for (size_t n = 0; n < _conn_map.size(); ++n) { for (size_t n = 0; n < _edge_map.size(); ++n) {
if (_conn_map[n][vertex]) { if (_edge_map[n][vertex]) {
res.push_back(n); res.push_back(n);
} }
} }
@@ -293,11 +293,11 @@ public:
/// \returns A list containing all vertices `x` that have symmetric edges with `vertex` /// \returns A list containing all vertices `x` that have symmetric edges with `vertex`
list<size_t> symmetric(size_t vertex) { list<size_t> symmetric(size_t vertex) {
list<size_t> res; list<size_t> res;
if (empty() || vertex >= _conn_map.size()) { if (empty() || vertex >= _edge_map.size()) {
return res; return res;
} }
for (const auto& it : _conn_map[vertex]) { for (const auto& it : _edge_map[vertex]) {
if (_conn_map[it.first][vertex]) { if (_edge_map[it.first][vertex]) {
res.push_back(it.first); res.push_back(it.first);
} }
} }
@@ -314,11 +314,11 @@ public:
/// \returns A list containing all vertices `x` that have symmetric edges with `vertex` /// \returns A list containing all vertices `x` that have symmetric edges with `vertex`
list<size_t> undirected(size_t vertex) { list<size_t> undirected(size_t vertex) {
list<size_t> res; list<size_t> res;
if (empty() || vertex >= _conn_map.size()) { if (empty() || vertex >= _edge_map.size()) {
return res; return res;
} }
for (const auto& it : _conn_map[vertex]) { for (const auto& it : _edge_map[vertex]) {
const auto* at = _conn_map[it.first][vertex]; const auto* at = _edge_map[it.first][vertex];
if (at != nullptr && *at == it.second) { if (at != nullptr && *at == it.second) {
res.push_back(it.first); res.push_back(it.first);
} }
@@ -332,10 +332,10 @@ public:
/// \param vertex The id of the vertex /// \param vertex The id of the vertex
/// \returns A pointer to a map containing edges mapped from this vertex /// \returns A pointer to a map containing edges mapped from this vertex
const auto* edges(size_t vertex) { const auto* edges(size_t vertex) {
if (empty() || vertex >= _conn_map.size()) { if (empty() || vertex >= _edge_map.size()) {
return nullptr; return nullptr;
} }
return &_conn_map[vertex]; return &_edge_map[vertex];
} }
/// @} /// @}
@@ -392,19 +392,19 @@ public:
return; return;
} }
if (_conn_map.size() < _vertex_pool.capacity()) { if (_edge_map.size() < _vertex_pool.capacity()) {
_conn_map.resize(_vertex_pool.capacity()); _edge_map.resize(_vertex_pool.capacity());
} }
auto it = _conn_map[a][b]; auto it = _edge_map[a][b];
size_t conn; size_t conn;
if (it != nullptr) { if (it != nullptr) {
conn = *it; conn = *it;
_conn_pool[conn] = vertex_t(fennec::forward<ArgsT>(args)...); _edge_pool[conn] = vertex_t(fennec::forward<ArgsT>(args)...);
} else { } else {
conn = _conn_pool.emplace(fennec::forward<ArgsT>(args)...); conn = _edge_pool.emplace(fennec::forward<ArgsT>(args)...);
} }
_conn_map[a].emplace(b, conn); _edge_map[a].emplace(b, conn);
} }
/// ///
@@ -419,21 +419,21 @@ public:
return; return;
} }
if (_conn_map.size() < _vertex_pool.capacity()) { if (_edge_map.size() < _vertex_pool.capacity()) {
_conn_map.resize(_vertex_pool.capacity()); _edge_map.resize(_vertex_pool.capacity());
} }
auto it = _conn_map[a][b]; auto it = _edge_map[a][b];
size_t conn; size_t conn;
if (it != nullptr) { if (it != nullptr) {
conn = *it; conn = *it;
_conn_pool[conn] = vertex_t(fennec::forward<ArgsT>(args)...); _edge_pool[conn] = vertex_t(fennec::forward<ArgsT>(args)...);
} else { } else {
conn = _conn_pool.emplace(fennec::forward<ArgsT>(args)...); conn = _edge_pool.emplace(fennec::forward<ArgsT>(args)...);
} }
_conn_map[a].emplace(b, conn); _edge_map[a].emplace(b, conn);
_conn_map[b].emplace(a, conn); _edge_map[b].emplace(a, conn);
} }
/// ///
@@ -443,20 +443,20 @@ public:
constexpr void cut_edge(size_t a, size_t b) { constexpr void cut_edge(size_t a, size_t b) {
// Find the edge object // Find the edge object
const auto* it = _conn_map[a][b]; const auto* it = _edge_map[a][b];
if (not it) { if (not it) {
return; return;
} }
size_t c = *it; size_t c = *it;
// Check if undirected // Check if undirected
const auto* at = _conn_map[b][a]; const auto* at = _edge_map[b][a];
if (not at || *at != c) { if (not at || *at != c) {
_conn_pool.erase(c); _edge_pool.erase(c);
} }
// Erase the edge mapping // Erase the edge mapping
_conn_map[a].erase(b); _edge_map[a].erase(b);
} }
/// ///
@@ -464,15 +464,15 @@ public:
/// \param a The first vertex id /// \param a The first vertex id
/// \param b The second vertex id /// \param b The second vertex id
constexpr void cut_edge2(size_t a, size_t b) { constexpr void cut_edge2(size_t a, size_t b) {
const auto* ita = _conn_map[a][b]; const auto* ita = _edge_map[a][b];
const auto* itb = _conn_map[a][b]; const auto* itb = _edge_map[a][b];
if (not (ita || itb)) { if (not (ita || itb)) {
return; return;
} }
if (ita) _conn_pool.erase(*ita); if (ita) _edge_pool.erase(*ita);
if (itb) _conn_pool.erase(*itb); if (itb) _edge_pool.erase(*itb);
_conn_map[a].erase(b); _edge_map[a].erase(b);
_conn_map[b].erase(a); _edge_map[b].erase(a);
} }
/// ///
@@ -491,8 +491,8 @@ public:
/// \brief Clear the graph, destructing all vertices and edges. /// \brief Clear the graph, destructing all vertices and edges.
void clear() { void clear() {
_vertex_pool.clear(); _vertex_pool.clear();
_conn_pool.clear(); _edge_pool.clear();
_conn_map.clear(); _edge_map.clear();
} }
/// @} /// @}
@@ -503,8 +503,8 @@ public:
private: private:
vertex_pool_t _vertex_pool; vertex_pool_t _vertex_pool;
edge_pool_t _conn_pool; edge_pool_t _edge_pool;
edge_map_t _conn_map; edge_map_t _edge_map;
template<typename...ArgsT> template<typename...ArgsT>
size_t _insert(ArgsT&&...args) { size_t _insert(ArgsT&&...args) {

View File

@@ -72,16 +72,15 @@ private:
struct node; struct node;
public: public:
///< Alias for the allocator type, rebound to list nodes /// \brief Alias for the allocator type, rebound to list nodes
using alloc_t = typename allocator_traits<Alloc>::template rebind<node>; using alloc_t = typename allocator_traits<Alloc>::template rebind<node>;
using value_t = TypeT; using value_t = TypeT; ///< Alias for the value type
using elem_t = node;
static constexpr size_t npos = -1; static constexpr size_t npos = -1; ///< Constant representing a non-existant position
class iterator; class iterator; ///< Iterator type for forward iteration over the list
class const_iterator; class const_iterator; ///< Iterator type for forward iteration over a constant list
// Constructors & Destructor =========================================================================================== // Constructors & Destructor ===========================================================================================
@@ -529,7 +528,7 @@ public:
}; };
private: private:
allocation<elem_t, alloc_t> _table; allocation<node, alloc_t> _table;
dynarray<size_t> _freed; dynarray<size_t> _freed;
size_t _root, _last, _size; size_t _root, _last, _size;

View File

@@ -81,15 +81,15 @@ struct map {
// Definitions ========================================================================================================= // Definitions =========================================================================================================
public: public:
struct key_hash; struct key_hash; ///< Hash for node keys
struct node_equals; struct key_equals; ///< Comparison for node keys
using key_t = KeyT; using key_t = KeyT; ///< The key type
using value_t = ValueT; using value_t = ValueT; ///< The value type
using elem_t = pair<KeyT, ValueT>; using elem_t = pair<KeyT, ValueT>; ///< then node type
using alloc_t = typename allocator_traits<Alloc>::template rebind<elem_t>; using alloc_t = typename allocator_traits<Alloc>::template rebind<elem_t>; ///< Rebinds the allocator type to nodes
using hash_t = Hash; using hash_t = Hash; ///< The hash type
using set_t = set<elem_t, key_hash, node_equals, alloc_t>; using set_t = set<elem_t, key_hash, key_equals, alloc_t>; ///< The underlying set
using iterator = set_t::iterator; using iterator = set_t::iterator; ///< Iterator type
// We only want to hash the key // We only want to hash the key
struct key_hash : hash_t { struct key_hash : hash_t {
@@ -99,7 +99,7 @@ public:
}; };
// We only want to compare the keys // We only want to compare the keys
struct node_equals : equality<KeyT> { struct key_equals : equality<KeyT> {
constexpr bool operator()(const elem_t& a, const elem_t& b) const { constexpr bool operator()(const elem_t& a, const elem_t& b) const {
return equality<KeyT>::operator()(a.first, b.first); return equality<KeyT>::operator()(a.first, b.first);
} }
@@ -248,7 +248,7 @@ public:
} }
/// ///
/// \brief Clears the set, destructing all elements /// \brief Clears the map destructing all elements
void clear() { void clear() {
_set.clear(); _set.clear();
} }

View File

@@ -550,7 +550,7 @@ private:
template<typename...ArgsT> template<typename...ArgsT>
constexpr void _insert(ArgsT&&...args) { constexpr void _insert(ArgsT&&...args) {
if (_size == 0 or static_cast<double>(_size) / capacity() >= _load) { // expand when full if (_size == 0 or static_cast<float>(_size) / capacity() >= _load) { // expand when full
_expand(); _expand();
} }
@@ -578,7 +578,7 @@ private:
equal_t _equal; equal_t _equal;
size_t _size; size_t _size;
size_t _sumpsl; size_t _sumpsl;
double _load; float _load;
}; };
} }

View File

@@ -159,20 +159,25 @@ public:
/// ///
/// \brief Move Insertion, inserts a copy of `x` into the pool /// \brief Emplacement, constructs a new object using `args...`
/// \param x the object to copy /// \param args The arguments to construct the new object with
/// \returns An integer corresponding to the id of the node /// \returns An integer corresponding to the id of the node
template<typename...ArgsT> template<typename...ArgsT>
constexpr size_t emplace(ArgsT&&...args) { constexpr size_t emplace(ArgsT&&...args) {
return this->_insert(fennec::forward<ArgsT>(args)...); return this->_insert(fennec::forward<ArgsT>(args)...);
} }
///
/// \brief Erase an object from the pool
/// \param i The id of the object
constexpr void erase(size_t i) { constexpr void erase(size_t i) {
_table[i] = nullopt; _table[i] = nullopt;
_freed.push_back(i); _freed.push_back(i);
--_size; --_size;
} }
/// @}
private: private:
dynarray<elem_t, AllocT> _table; dynarray<elem_t, AllocT> _table;
list<size_t> _freed; list<size_t> _freed;

View File

@@ -304,7 +304,7 @@ public:
/// ///
/// \returns The next node id were `insert` or `emplace` to be called /// \returns The next node id were `insert` or `emplace` to be called
constexpr size_t next_free() const { constexpr size_t next_id() const {
size_t i = _size; size_t i = _size;
if (not _freed.empty()) { if (not _freed.empty()) {
i = _freed.front(); i = _freed.front();
@@ -418,7 +418,10 @@ public:
OrderT order; OrderT order;
i = order(*this, i); i = order(*this, i);
while (i != npos) { while (i != npos) {
uint8_t mode = visit(*_table[i].value, i); uint8_t mode = traversal_control_continue;
if (_table[i].value) {
mode = visit(*_table[i].value, i);
}
if (mode == traversal_control_break) { if (mode == traversal_control_break) {
break; break;
} }

View File

@@ -216,7 +216,7 @@ public:
// Check the first element; // Check the first element;
if (_alloc[i].psl >= psl && _alloc[i].value) { if (_alloc[i].psl >= psl && _alloc[i].value) {
if (*_alloc[i].value == val) { if (_equal(*_alloc[i].value, val)) {
return iterator(this, i); return iterator(this, i);
} }
} }
@@ -230,13 +230,13 @@ public:
bool c0 = p0 >= 0 && _alloc[i0].psl >= p0, c1 = _alloc[i1].psl >= p1; // Check that we are in range 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 (c0 && _alloc[i0].value) {
if (*_alloc[i0].value == val) { if (_equal(*_alloc[i0].value, val)) {
return iterator(this, i0); return iterator(this, i0);
} }
} }
if (c1 && _alloc[i1].value) { if (c1 && _alloc[i1].value) {
if (*_alloc[i1].value == val) { if (_equal(*_alloc[i1].value, val)) {
return iterator(this, i1); return iterator(this, i1);
} }
} }
@@ -455,7 +455,7 @@ private:
template<typename...ArgsT> template<typename...ArgsT>
constexpr iterator _insert(ArgsT&&...args) { constexpr iterator _insert(ArgsT&&...args) {
if (_size == 0 or double(_size) / capacity() >= _load) { // expand when full if (_size == 0 or static_cast<float>(_size) / capacity() >= _load) { // expand when full
_expand(); _expand();
} }
@@ -484,7 +484,7 @@ private:
equal_t _equal; equal_t _equal;
size_t _size; size_t _size;
size_t _sumpsl; size_t _sumpsl;
double _load; float _load;
}; };
} }

View File

@@ -16,7 +16,19 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// ===================================================================================================================== // =====================================================================================================================
#ifndef FENNEC_CONCURRENCY_MUTEX_H ///
#define FENNEC_CONCURRENCY_MUTEX_H /// \file variant.h
/// \brief Contains the definition for a structure that holds a single value from multiple types
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#endif // FENNEC_CONCURRENCY_MUTEX_H #ifndef FENNEC_CONTAINERS_VARIANT_H
#define FENNEC_CONTAINERS_VARIANT_H
#endif // FENNEC_CONTAINERS_VARIANT_H

View File

@@ -26,6 +26,8 @@
#define __PTRDIFF_TYPE__ ptrdiff_t #define __PTRDIFF_TYPE__ ptrdiff_t
#endif #endif
// Include math since stdint will define its own versions of isinf and isnan
#include <math.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>

View File

@@ -42,6 +42,22 @@ FENNEC_NO_INLINE uint64_t typeuuid() {
return id = detail::_typeuuid<RootT>(); return id = detail::_typeuuid<RootT>();
} }
template<typename RootT = void>
struct typed {
public:
const uint64_t type;
template<typename TypeT>
bool is_type() const {
return type == typeuuid<TypeT, RootT>();
}
template<typename TypeT>
typed(TypeT*)
: type(typeuuid<TypeT, RootT>()) {
}
};
} }
#endif // FENNEC_LANG_TYPEUUID_H #endif // FENNEC_LANG_TYPEUUID_H

View File

@@ -248,7 +248,7 @@ public:
bool eof() const; bool eof() const;
// Read Operations ===================================================================================================== // Binary Read Operations ==============================================================================================
char getc(); char getc();
wchar_t getwc(); wchar_t getwc();
@@ -269,7 +269,7 @@ public:
wstring getwline(); wstring getwline();
// Write Operations ==================================================================================================== // Binary Write Operations =============================================================================================
bool putc(char c); bool putc(char c);
bool putwc(wchar_t c); bool putwc(wchar_t c);

View File

@@ -55,7 +55,7 @@ public:
/// \param str the cstring to convert /// \param str the cstring to convert
path(const cstring& str) path(const cstring& str)
: _str(str) { : _str(str) {
while (not _str.empty() && _str[_str.size() - 1] == '/') { if (str.size() > 2 && str[str.size() - 1] == '/') {
_str = _str.substring(0, str.size() - 1); _str = _str.substring(0, str.size() - 1);
} }
} }
@@ -64,8 +64,8 @@ public:
/// \brief String Conversion Constructor /// \brief String Conversion Constructor
/// \param str the string to convert /// \param str the string to convert
path(const string& str) path(const string& str)
: _str(str) { : _str(str) {
while (_str[_str.size() - 1] == '/') { if (str.size() > 2 && str[str.size() - 1] == '/') {
_str = _str.substring(0, str.size() - 1); _str = _str.substring(0, str.size() - 1);
} }
} }
@@ -85,6 +85,16 @@ public:
// Assignment Operators ================================================================================================ // Assignment Operators ================================================================================================
///
/// \brief C-String Assignment Operator
/// \param str the cstring to assign
/// \returns a reference to `this` after assigning `p`
template<size_t n>
path& operator=(const char (&str)[n]) {
_str = str;
return *this;
}
/// ///
/// \brief C-String Assignment Operator /// \brief C-String Assignment Operator
/// \param p the cstring to assign /// \param p the cstring to assign
@@ -145,6 +155,7 @@ public:
} }
const string& str() const { return _str; } const string& str() const { return _str; }
const char* cstr() const { return _str.cstr(); }
bool empty() { bool empty() {
size_t size = _str.size(); size_t size = _str.size();
@@ -176,7 +187,7 @@ public:
#else #else
size_t start = _str.size() - 1; size_t start = _str.size() - 1;
start = _str[start] == '/' ? start - 1 : start; start = _str[start] == '/' ? start - 1 : start;
return _str.substring(0, _str.rfind('/', start)); return path(_str.substring(0, _str.rfind('/', start)));
#endif #endif
} }
@@ -195,7 +206,7 @@ public:
while (not parse.empty()) { while (not parse.empty()) {
// Handle dots // Handle dots
while (parse._str[0] == '.') { while (not parse.empty() && parse._str[0] == '.') {
// Check for ".." // Check for ".."
if (parse._str[1] == '.') { if (parse._str[1] == '.') {
// ".." // ".."

View File

@@ -171,6 +171,10 @@ public:
/// \returns the size of the string excluding its null terminator, i.e. `(*str)[size()] == '\0'` /// \returns the size of the string excluding its null terminator, i.e. `(*str)[size()] == '\0'`
constexpr size_t size() const { return _size; } constexpr size_t size() const { return _size; }
///
/// \returns the size of the string including its null terminator, i.e. `(*str)[capacity() - 1] == '\0'`
constexpr size_t capacity() const { return _size + 1; }
constexpr bool empty() const { constexpr bool empty() const {
return _cstr == nullptr || _size == 0; return _cstr == nullptr || _size == 0;
} }
@@ -198,9 +202,16 @@ public:
} }
/// ///
/// \brief Dereference Operator /// \brief Data Access
/// \returns A const qualified pointer to the underlying allocation /// \returns A const qualified pointer to the underlying allocation
constexpr const char* operator*() const { constexpr char* data() {
return _str;
}
///
/// \brief Data Access
/// \returns A const qualified pointer to the underlying allocation
constexpr const char* data() const {
return _cstr; return _cstr;
} }
@@ -330,8 +341,8 @@ private:
template<> template<>
struct hash<cstring> : hash<byte_array> { struct hash<cstring> : hash<byte_array> {
constexpr size_t operator()(const cstring& str) { constexpr size_t operator()(const cstring& str) const {
return hash<byte_array>::operator()(byte_array(*str, str.size())); return hash<byte_array>::operator()(byte_array(str, str.size()));
} }
}; };

View File

@@ -59,114 +59,104 @@ public:
} }
/// ///
/// \brief Sized Constructor, initializes a null-terminated string of size `n` with null characters /// \brief Sized Constructor, initializes a null-terminated string of size `n` with `'c'...`
/// \param n the number of characters /// \param n the number of characters
///
/// \details adds additional character for null termination.
constexpr _string(size_t n)
: _string('\0', n) {
}
///
/// \brief Sized Constructor, initializes a null-terminated string of size `n` filled with the character `c`
/// \param c the character to fill with /// \param c the character to fill with
/// \param n the number of characters
/// ///
/// \details adds additional character for null termination. /// \details adds additional character for null termination.
constexpr _string(char c, size_t n) constexpr _string(size_t n, char c = '\0')
: _str(n + 1) { : _str(n + 1) {
fennec::memset(_str.data(), c, n); fennec::memset(_str, c, n);
_str[n] = '\0'; }
constexpr _string(const alloc_t& alloc)
: _str(alloc) {
}
constexpr _string(size_t n, char c, const alloc_t& alloc)
: _str(n + 1, alloc) {
fennec::memset(_str, c, n);
}
constexpr _string(const cstring& cstr)
: _str(cstr, cstr.size() + 1) {
} }
/// ///
/// \brief Buffer Copy Constructor /// \brief Buffer Constructor, wraps the provided C-Style string, appending a null-terminator if not present
/// \param str the buffer to copy
/// \param n number of characters in the buffer
///
/// \details adds additional character for null termination. Ignores whether str is null-terminated.
/// This constructor makes the assumption that `n` is the intended number of characters.
constexpr _string(char* str, size_t n)
: _str(str[n - 1] == '\0' ? n : n + 1) {
fennec::memcpy(_str.data(), str, n);
if (str[n - 1] != '\0') _str[n] = '\0';
}
///
/// \brief Buffer Constructor, wraps the provided C-Style string
/// \param str the buffer to wrap /// \param str the buffer to wrap
/// \tparam n the number of characters in the buffer plus the null terminator /// \tparam n the number of characters in the buffer including the null-terminator, if present
template<size_t n> template<size_t n>
explicit constexpr _string(char(&str)[n]) explicit constexpr _string(const char (&str)[n])
: _str(str, n) { : _str(str[n - 1] != '\0' ? n + 1 : n) {
assert(_str[n - 1] == '\0', "Invalid NTBS."); fennec::memcpy(_str, str, n);
if (str[n - 1] != '\0') {
_str[n] = '\0';
}
} }
/// ///
/// \brief Buffer Copy Constructor /// \brief Buffer Constructor, wraps the provided C-Style string, appending a null-terminator if not present
/// \param str the buffer to copy
/// \param n number of characters in the buffer
///
/// \details adds additional character for null termination. Ignores whether str is null-terminated.
/// This constructor makes the assumption that `n` is the intended number of characters.
constexpr _string(const char* str, size_t n)
: _str(str[n - 1] == '\0' ? n : n + 1) {
fennec::memcpy(_str.data(), str, n);
if (str[n - 1] != '\0') _str[n] = '\0';
}
///
/// \brief Buffer Constructor, wraps the provided C-Style string
/// \param str the buffer to wrap /// \param str the buffer to wrap
/// \tparam n the number of characters in the buffer plus the null terminator /// \param n the number of characters in the buffer including the null-terminator, if present
template<size_t n> constexpr _string(const char* buf, size_t n)
explicit constexpr _string(const char(&str)[n]) : _str(buf[n - 1] != '\0' ? n + 1 : n) {
: _str(str, n) { fennec::memcpy(_str, buf, n);
assert(_str[n - 1] == '\0', "Invalid NTBS."); if (buf[n - 1] != '\0') {
} _str[n] = '\0';
}
///
/// \brief Buffer Copy Constructor
/// \param str the buffer to copy
constexpr _string(const cstring& str)
: _str(str, str.size() + 1) {
} }
/// ///
/// \brief String Copy Constructor /// \brief String Copy Constructor
/// \param str the string to copy /// \param str the string to copy
constexpr _string(const _string& str) constexpr _string(const _string& str) = default;
: _str(str._str) {
}
constexpr _string(_string&& str) noexcept
: _str(fennec::move(str._str)) {
}
/// ///
/// \brief String Destructor, cleans up the underlying allocation /// \brief String Move Constructor
constexpr ~_string() = default; // allocation cleans up itself /// \param str the string to take ownership of
constexpr _string(_string&& str) noexcept = default;
///
/// \brief Destructor, cleans up underlying allocation
constexpr ~_string() = default;
// Assignment ==========================================================================================================
constexpr _string& operator=(const cstring& cstr) {
_str.callocate(cstr.capacity());
fennec::memcpy(_str, cstr, cstr.capacity());
return *this;
}
constexpr _string& operator=(const _string& str) = default;
constexpr _string& operator=(_string&& str) noexcept = default;
// Properties ========================================================================================================== // Properties ==========================================================================================================
/// ///
/// \returns The size of the string excluding null terminator /// \returns The size of the string excluding null terminator
constexpr size_t size() const { constexpr size_t size() const {
return _str.capacity() - 1; return _str.capacity() > 0 ? _str.capacity() - 1 : 0;
}
///
/// \returns The size of the string including null terminator
constexpr size_t capacity() const {
return _str.capacity();
} }
constexpr bool empty() const { constexpr bool empty() const {
return size() == 0; return size() == 0;
} }
// Access ============================================================================================================== // Access ==============================================================================================================
/// ///
/// \brief Array Access Operator /// \brief Array Access Operator
/// \param i the index to access /// \param i the index to access
/// \returns a reference to the character /// \returns a reference to the character
constexpr char& operator[](int i) { constexpr char& operator[](size_t i) {
return _str[i]; return _str[i];
} }
@@ -174,24 +164,21 @@ public:
/// \brief Const-Array Access Operator /// \brief Const-Array Access Operator
/// \param i the index to access /// \param i the index to access
/// \returns a copy of the character /// \returns a copy of the character
constexpr char operator[](int i) const { constexpr const char& operator[](size_t i) const {
assertd(i >= 0 && (size_t)i < size(), "Array Out of Bounds");
return _str[i]; return _str[i];
} }
/// constexpr char* data() {
/// \brief Dereference Operator return _str;
/// \returns A const qualified pointer to the underlying allocation
constexpr const char* operator*() const {
return _str.data();
} }
/// constexpr const char* data() const {
/// \brief Implicit Dereference Cast return _str;
constexpr operator const char*() const {
return _str.data();
} }
constexpr const char* cstr() const {
return _str;
}
// Examination ========================================================================================================= // Examination =========================================================================================================
@@ -212,7 +199,7 @@ public:
} }
n = fennec::min(n, fennec::max(_str, str.size()) + 1); n = fennec::min(n, fennec::max(_str, str.size()) + 1);
return ::strncmp(_str.data() + i, str, n); return ::strncmp(_str + i, str, n);
} }
/// ///
@@ -226,7 +213,7 @@ public:
} }
n = min(n, max(size(), str.size()) + 1); n = min(n, max(size(), str.size()) + 1);
return ::strncmp(_str.data() + i, str, n); return ::strncmp(_str + i, str.data(), n);
} }
constexpr bool operator==(const _string& str) const { constexpr bool operator==(const _string& str) const {
@@ -242,8 +229,8 @@ public:
return size(); return size();
} }
const char* loc = ::strchr(_str.data() + i, c); // get location using strchr const char* loc = ::strchr(_str + i, c); // get location using strchr
return loc ? loc - _str.data() : size(); // return size if not found return loc ? loc - _str : size(); // return size if not found
} }
/// ///
@@ -332,63 +319,6 @@ public:
return size(); // base case return size(); // base case
} }
// Manipulation ========================================================================================================
///
/// \brief Resize the string, filling additional bytes with `'\0'`
/// \param n the new size of the string
constexpr void resize(size_t n) {
size_t i = size();
_str.reallocate(n + 1);
if (n > i) fennec::memset(_str.data() + i, '\0', n + 1 - i);
}
///
/// \brief Copy Assignment Operator
/// \param str the string to copy
/// \returns a reference to `this`
constexpr _string& operator=(const cstring& str) {
if (str.empty()) {
_str.deallocate();
return *this;
}
resize(str.size());
fennec::memcpy(_str.data(), str, str.size());
_str[str.size()] = '\0';
return *this;
}
///
/// \brief Copy Assignment Operator
/// \param str the string to copy
/// \returns a reference to `this`
constexpr _string& operator=(const string& str) {
resize(str.size());
fennec::memcpy(_str.data(), str, str.size());
_str[str.size()] = '\0';
return *this;
}
///
/// \brief Move Assignment Operator
/// \param str the string to move
/// \returns a reference to `this`
constexpr _string& operator=(string&& str) noexcept {
_str = move(str._str);
return *this;
}
///
/// \brief Replace all instances of `x` with `y`
/// \param x the character to search for
/// \param y the character to replace with
void replace(char x, char y) {
size_t i = 0;
while ((i = find(x, 0)) != size()) {
_str[i] = y;
}
}
/// ///
/// \brief Retrieve a substring of a string /// \brief Retrieve a substring of a string
/// \param i the start index /// \param i the start index
@@ -398,60 +328,98 @@ public:
if (i >= size()) { if (i >= size()) {
return _string(""); return _string("");
} }
n = min(n, size() - i); n = fennec::min(n, size() - i);
return _string(_str.data() + i, n); _string res;
} res._str.callocate(n + 1);
fennec::memcpy(res.data(), _str + i, n);
///
/// \brief Returns a string with `c` appended to it
/// \param c
/// \returns
constexpr _string operator+(char c) const {
// Copy contents with one additional byte.
_string res(_str.data(), _str.size() + 1);
res[size()] = c; // Set the last character to c
return res; return res;
} }
friend constexpr _string operator+(char c, _string& str) {
return _string(c, 1) + str;
// Modifiers ===========================================================================================================
constexpr void resize(size_t n) {
_str.creallocate(n + 1);
_str[size()] = '\0';
} }
constexpr _string operator+(const cstring& str) const { constexpr _string operator+(char c) const {
_string res(size() + str.size()); // Make a new string with the size of this + str if (_str == nullptr) {
fennec::memcpy(&res[0], _str.data(), size()); // Copy the contents of this return _string(1, c);
fennec::memcpy(&res[size()], str, str.size()); // Append the contents of str }
_string res;
res._str.callocate(capacity() + 1);
fennec::memcpy(res.data(), _str, size());
res[size()] = c;
return res;
}
friend constexpr _string operator+(char c, const _string& str) {
_string res(1, c);
return res += str;
}
constexpr _string operator+(const cstring& cstr) const {
if (_str == nullptr) {
return _string(cstr);
}
_string res;
res._str.callocate(size() + cstr.size() + 1);
fennec::memcpy(res.data(), _str, size());
fennec::memcpy(res.data() + size(), cstr, cstr.size());
return res; return res;
} }
constexpr _string operator+(const _string& str) const { constexpr _string operator+(const _string& str) const {
_string res(size() + str.size()); // Make a new string with the size of this + str if (_str == nullptr) {
fennec::memcpy(&res[0], _str.data(), size()); // Copy the contents of this return _string(str);
fennec::memcpy(&res[size()], str, str.size()); // Append the contents of str }
if (str.data() == nullptr) {
return _string(*this);
}
_string res;
res._str.callocate(size() + str.size() + 1);
fennec::memcpy(res.data(), _str, size());
fennec::memcpy(res.data() + size(), str.data(), str.size());
return res; return res;
} }
constexpr _string& operator+=(char c) { constexpr _string& operator+=(char c) {
size_t x = size(); if (_str == nullptr) {
resize(x + 1); _str.callocate(2);
_str[x] = c; _str[0] = c;
return *this;
}
_str.creallocate(capacity() + 1);
_str[size() - 1] = c;
return *this; return *this;
} }
constexpr _string& operator+=(const cstring& str) { constexpr _string& operator+=(const cstring& cstr) {
size_t x = size(); if (_str == nullptr) {
resize(x + str.size()); return *this = cstr;
fennec::memcpy(&_str[x], str, str.size()); }
size_t middle = size();
_str.creallocate(middle + cstr.size() + 1);
fennec::memcpy(_str + middle, cstr, cstr.size());
return *this; return *this;
} }
constexpr _string& operator+=(const _string& str) { constexpr _string& operator+=(const _string& str) {
size_t x = size(); if (_str == nullptr) {
resize(x + str.size()); return *this = str;
fennec::memcpy(&_str[x], str, str.size()); }
if (str.data() == nullptr) {
return *this;
}
size_t middle = size();
_str.creallocate(middle + str.size() + 1);
fennec::memcpy(_str + middle, str.data(), str.size());
return *this; return *this;
} }
private: private:
alloc_t _str; alloc_t _str;
}; };
@@ -459,7 +427,7 @@ private:
template<> template<>
struct hash<string> : hash<byte_array> { struct hash<string> : hash<byte_array> {
constexpr size_t operator()(const string& str) const { constexpr size_t operator()(const string& str) const {
return hash<byte_array>::operator()(byte_array(*str, str.size())); return hash<byte_array>::operator()(byte_array(str.data(), str.size()));
} }
}; };

View File

@@ -66,9 +66,7 @@ public:
/// ///
/// \brief Default Constructor, initializes with nullptr /// \brief Default Constructor, initializes with nullptr
constexpr wcstring() constexpr wcstring()
: _str(nullptr) : _str(nullptr), _size(0), _const(true) {
, _size(0)
, _const(true) {
} }
/// ///
@@ -93,7 +91,7 @@ public:
/// \param str the buffer to wrap /// \param str the buffer to wrap
/// \tparam n the number of characters in the buffer plus the null terminator /// \tparam n the number of characters in the buffer plus the null terminator
template<size_t n> template<size_t n>
constexpr wcstring(wchar_t(&str)[n]) constexpr wcstring(wchar_t (&str)[n])
: _str(str) : _str(str)
, _size(n - 1) , _size(n - 1)
, _const(false) { , _const(false) {
@@ -116,7 +114,7 @@ public:
/// \param str the buffer to wrap /// \param str the buffer to wrap
/// \tparam n the number of characters in the buffer plus the null terminator /// \tparam n the number of characters in the buffer plus the null terminator
template<size_t n> template<size_t n>
constexpr wcstring(const wchar_t(&str)[n]) constexpr wcstring(const wchar_t (&str)[n])
: _cstr(str) : _cstr(str)
, _size(n - 1) , _size(n - 1)
, _const(true) { , _const(true) {
@@ -148,7 +146,7 @@ public:
template<size_t n> template<size_t n>
constexpr wcstring& operator=(wchar_t(&str)[n]) { constexpr wcstring& operator=(wchar_t(&str)[n]) {
assert(_str[n - 1] == '\0', "Invalid NTBS."); assert(_str[n - 1] == '\0', "Invalid NTBS.");
_str = str; _size = n - 1; _const = false; _str = str, _size = n - 1, _const = false;
return *this; return *this;
} }
@@ -175,6 +173,10 @@ public:
/// \returns the size of the string excluding its null terminator, i.e. `(*str)[size()] == '\0'` /// \returns the size of the string excluding its null terminator, i.e. `(*str)[size()] == '\0'`
constexpr size_t size() const { return _size; } constexpr size_t size() const { return _size; }
///
/// \returns the size of the string including its null terminator, i.e. `(*str)[capacity() - 1] == '\0'`
constexpr size_t capacity() const { return _size + 1; }
constexpr bool empty() const { constexpr bool empty() const {
return _cstr == nullptr || _size == 0; return _cstr == nullptr || _size == 0;
} }
@@ -196,15 +198,22 @@ public:
/// \brief Const-Array Access Operator /// \brief Const-Array Access Operator
/// \param i the index to access /// \param i the index to access
/// \returns a copy of the character /// \returns a copy of the character
constexpr wchar_t operator[](size_t i) const { constexpr const wchar_t& operator[](size_t i) const {
assertd(i < size(), "Array Out of Bounds"); assertd(i < size(), "Array Out of Bounds");
return _cstr[i]; return _cstr[i];
} }
/// ///
/// \brief Dereference Operator /// \brief Data Access
/// \returns A const qualified pointer to the underlying allocation /// \returns A const qualified pointer to the underlying allocation
constexpr const wchar_t* operator*() const { constexpr wchar_t* data() {
return _str;
}
///
/// \brief Data Access
/// \returns A const qualified pointer to the underlying allocation
constexpr const wchar_t* data() const {
return _cstr; return _cstr;
} }
@@ -220,12 +229,14 @@ public:
/// ///
/// \returns The length of the string to the first null-terminator /// \returns The length of the string to the first null-terminator
constexpr size_t length() const { constexpr size_t length() const {
return find(L'\0'); return find('\0');
} }
/// ///
/// \brief String Comparison /// \brief String Comparison
/// \param str the string to compare against /// \param str the string to compare against
/// \param i the index to start at
/// \param n the number of characters to compare
/// \returns Zero if both strings are equal, otherwise a negative value if lhs appears before rhs according to the /// \returns Zero if both strings are equal, otherwise a negative value if lhs appears before rhs according to the
/// current locale, otherwise a positive value. /// current locale, otherwise a positive value.
constexpr int compare(const wcstring& str, size_t i = 0, size_t n = npos) const { constexpr int compare(const wcstring& str, size_t i = 0, size_t n = npos) const {
@@ -237,6 +248,15 @@ public:
return ::wcsncmp(_cstr + i, str, n); return ::wcsncmp(_cstr + i, str, n);
} }
///
/// \brief String Equality
/// \param str the string to compare against
/// \returns True if all characters are equal, false otherwise
template<size_t n>
constexpr bool operator==(const wchar_t (&str)[n]) const {
return compare(wcstring(str)) == 0;
}
/// ///
/// \brief String Equality /// \brief String Equality
/// \param str the string to compare against /// \param str the string to compare against
@@ -278,7 +298,7 @@ public:
/// \param c the string to find /// \param c the string to find
/// \param i the index to start at /// \param i the index to start at
/// \returns The index of `c` if it occurs in the string, otherwise returns `size()` /// \returns The index of `c` if it occurs in the string, otherwise returns `size()`
constexpr size_t rfind(wchar_t c, size_t i = npos) const { constexpr size_t rfind(char c, size_t i = npos) const {
if (_size == 0) { if (_size == 0) {
return _size; return _size;
} }
@@ -300,7 +320,7 @@ public:
return _size; return _size;
} }
const wchar_t first = str[0]; const char first = str[0];
i = min(i, _size - str._size); i = min(i, _size - str._size);
do { do {
if(_cstr[i] == first) { if(_cstr[i] == first) {
@@ -321,6 +341,13 @@ private:
bool _const; bool _const;
}; };
template<>
struct hash<wcstring> : hash<byte_array> {
constexpr size_t operator()(const wcstring& str) const {
return hash<byte_array>::operator()(byte_array(str, str.size()));
}
};
} }
#endif // FENNEC_LANGPROC_STRINGS_wcstring_H #endif // FENNEC_LANGPROC_STRINGS_wcstring_H

View File

@@ -16,8 +16,8 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// ===================================================================================================================== // =====================================================================================================================
#ifndef FENNEC_LANGPROC_wstringS_wstring_H #ifndef FENNEC_LANGPROC_wstringS_WSTRING_H
#define FENNEC_LANGPROC_wstringS_wstring_H #define FENNEC_LANGPROC_wstringS_WSTRING_H
#include <fennec/langproc/strings/detail/_ctype.h> #include <fennec/langproc/strings/detail/_ctype.h>
#include <fennec/langproc/strings/wcstring.h> #include <fennec/langproc/strings/wcstring.h>
@@ -59,110 +59,126 @@ public:
} }
/// ///
/// \brief Sized Constructor, initializes a null-terminated string of size `n` with null characters /// \brief Sized Constructor, initializes a null-terminated string of size `n` with `'c'...`
/// \param n the number of characters /// \param n the number of wchar_tacters
/// \param c the wchar_tacter to fill with
/// ///
/// \details adds additional character for null termination. /// \details adds additional wchar_tacter for null termination.
constexpr _wstring(size_t n) constexpr _wstring(size_t n, wchar_t c = '\0')
: _wstring('\0', n) {
}
///
/// \brief Sized Constructor, initializes a null-terminated string of size `n` filled with the character `c`
/// \param c the characters to fill with
/// \param n the number of characters
///
/// \details adds additional character for null termination.
constexpr _wstring(wchar_t c, size_t n)
: _str(n + 1) { : _str(n + 1) {
fennec::wmemset(_str.data(), c, n); _str[n] = '\0'; fennec::wmemset(_str, c, n);
}
constexpr _wstring(const alloc_t& alloc)
: _str(alloc) {
}
constexpr _wstring(size_t n, wchar_t c, const alloc_t& alloc)
: _str(n + 1, alloc) {
fennec::wmemset(_str, c, n);
}
constexpr _wstring(const wcstring& cstr)
: _str(cstr, cstr.size() + 1) {
} }
/// ///
/// \brief Buffer Copy Constructor /// \brief Buffer Constructor, wraps the provided C-Style string, appending a null-terminator if not present
/// \param str the buffer to copy /// \param str the buffer to wrap
/// \param len number of characters in the buffer /// \tparam n the number of wchar_tacters in the buffer including the null-terminator, if present
/// template<size_t n>
/// \details adds additional character for null termination. Ignores whether str is null-terminated. explicit constexpr _wstring(const wchar_t (&str)[n])
/// This constructor makes the assumption that `len` is the intended number of characters. : _str(str[n - 1] != '\0' ? n + 1 : n) {
constexpr _wstring(const wchar_t* str, size_t n) fennec::wmemcpy(_str, str, n);
: _str(str, n + 1) { if (str[n - 1] != '\0') {
::wcsncpy(_str.data(), str, n); _str[n] = '\0';
_str[n] = '\0'; }
} }
/// ///
/// \brief Buffer Copy Constructor /// \brief Buffer Constructor, wraps the provided C-Style string, appending a null-terminator if not present
/// \param str the buffer to copy /// \param str the buffer to wrap
/// \param len number of characters in the buffer /// \param n the number of wchar_tacters in the buffer including the null-terminator, if present
/// constexpr _wstring(const wchar_t* buf, size_t n)
/// \details adds additional character for null termination. Ignores whether str is null-terminated. : _str(buf[n - 1] != '\0' ? n + 1 : n) {
/// This constructor makes the assumption that `len` is the intended number of characters. fennec::wmemcpy(_str, buf, n);
constexpr _wstring(const wcstring& str) if (buf[n - 1] != '\0') {
: _str(str, str.size() + 1) { _str[n] = '\0';
_str[str.size()] = '\0'; }
} }
/// ///
/// \brief String Copy Constructor /// \brief String Copy Constructor
/// \param str the string to copy /// \param str the string to copy
constexpr _wstring(const wstring& str) constexpr _wstring(const _wstring& str) = default;
: _wstring(str, str.size() - 1) {
}
constexpr _wstring(_wstring&& str) noexcept
: _str(fennec::move(str._str)) {
}
/// ///
/// \brief String Destructor, cleans up the underlying allocation /// \brief String Move Constructor
constexpr ~_wstring() = default; // allocation cleans up itself /// \param str the string to take ownership of
constexpr _wstring(_wstring&& str) noexcept = default;
///
/// \brief Destructor, cleans up underlying allocation
constexpr ~_wstring() = default;
// Assignment ==========================================================================================================
constexpr _wstring& operator=(const wcstring& cstr) {
_str.callocate(cstr.capacity());
fennec::wmemcpy(_str, cstr, cstr.capacity());
return *this;
}
constexpr _wstring& operator=(const _wstring& str) = default;
constexpr _wstring& operator=(_wstring&& str) noexcept = default;
// Properties ========================================================================================================== // Properties ==========================================================================================================
/// ///
/// \returns The size of the string excluding null terminator /// \returns The size of the string excluding null terminator
constexpr size_t size() const { constexpr size_t size() const {
return _str.capacity() - 1; return _str.capacity() > 0 ? _str.capacity() - 1 : 0;
}
///
/// \returns The size of the string including null terminator
constexpr size_t capacity() const {
return _str.capacity();
} }
constexpr bool empty() const { constexpr bool empty() const {
return size() == 0; return size() == 0;
} }
// Access ============================================================================================================== // Access ==============================================================================================================
/// ///
/// \brief Array Access Operator /// \brief Array Access Operator
/// \param i the index to access /// \param i the index to access
/// \returns a reference to the character /// \returns a reference to the wchar_tacter
constexpr wchar_t& operator[](int i) { constexpr wchar_t& operator[](size_t i) {
return _str[i]; return _str[i];
} }
/// ///
/// \brief Const-Array Access Operator /// \brief Const-Array Access Operator
/// \param i the index to access /// \param i the index to access
/// \returns a copy of the character /// \returns a copy of the wchar_tacter
constexpr wchar_t operator[](int i) const { constexpr const wchar_t& operator[](size_t i) const {
assertd(i >= 0 && i < size(), "Array Out of Bounds");
return _str[i]; return _str[i];
} }
/// constexpr wchar_t* data() {
/// \brief Dereference Operator return _str;
/// \returns A const qualified pointer to the underlying allocation
constexpr const wchar_t* operator*() const {
return _str.data();
} }
/// constexpr const wchar_t* data() const {
/// \brief Implicit Dereference Cast return _str;
constexpr operator const wchar_t*() const {
return _str.data();
} }
constexpr const wchar_t* cstr() const {
return _str;
}
// Examination ========================================================================================================= // Examination =========================================================================================================
@@ -183,7 +199,7 @@ public:
} }
n = fennec::min(n, fennec::max(_str, str.size()) + 1); n = fennec::min(n, fennec::max(_str, str.size()) + 1);
return ::wcsncmp(_str.data() + i, str, n); return ::wcsncmp(_str + i, str, n);
} }
/// ///
@@ -191,13 +207,13 @@ public:
/// \param ostr the string to compare against /// \param ostr the string to compare against
/// \returns Zero if both strings are equal, otherwise a negative value if lhs appears before rhs according to the /// \returns Zero if both strings are equal, otherwise a negative value if lhs appears before rhs according to the
/// current locale, otherwise a positive value. /// current locale, otherwise a positive value.
constexpr int compare(const wstring& str, size_t i = 0, size_t n = npos) const { constexpr int compare(const _wstring& str, size_t i = 0, size_t n = npos) const {
if (i >= size()) { // bounds check if (i >= size()) { // bounds check
return -1; return -1;
} }
n = min(n, max(size(), str.size()) + 1); n = min(n, max(size(), str.size()) + 1);
return ::wcsncmp(_str.data() + i, str, n); return ::wcsncmp(_str + i, str.data(), n);
} }
constexpr bool operator==(const _wstring& str) const { constexpr bool operator==(const _wstring& str) const {
@@ -206,22 +222,22 @@ public:
/// ///
/// \brief Finds the index of the first occurrence of `c` in the string /// \brief Finds the index of the first occurrence of `c` in the string
/// \param c the character to find /// \param c the wchar_tacter to find
/// \returns The index of `c` if it occurs in the string, otherwise returns `size()` /// \returns The index of `c` if it occurs in the string, otherwise returns `size()`
constexpr size_t find(wchar_t c, size_t i = 0) const { constexpr size_t find(wchar_t c, size_t i = 0) const {
if (i >= size()) { // bounds check if (i >= size()) { // bounds check
return size(); return size();
} }
const wchar_t* loc = ::wcschr(_str.data() + i, c); // get location using strchr const wchar_t* loc = ::wcschr(_str + i, c); // get location using strchr
return loc ? loc - _str.data() : size(); // return size if not found return loc ? loc - _str : size(); // return size if not found
} }
/// ///
/// \brief Finds the index of the first occurrence of `str` in the string. /// \brief Finds the index of the first occurrence of `str` in the string.
/// \param str the string to find /// \param str the string to find
/// \returns The index of `str` if it occurs in the string, otherwise returns `size()` /// \returns The index of `str` if it occurs in the string, otherwise returns `size()`
constexpr size_t find(const wstring& str, size_t i = 0) const { // bounds check constexpr size_t find(const _wstring& str, size_t i = 0) const { // bounds check
if (i >= size()) { // bounds check if (i >= size()) { // bounds check
return size(); return size();
} }
@@ -287,7 +303,7 @@ public:
/// \param str the string to find /// \param str the string to find
/// \param i the index to start at /// \param i the index to start at
/// \returns The index of `str` if it occurs in the string, otherwise returns `size()` /// \returns The index of `str` if it occurs in the string, otherwise returns `size()`
constexpr size_t rfind(const wstring& str, size_t i = npos) const { constexpr size_t rfind(const string& str, size_t i = npos) const {
if (size() == 0) { if (size() == 0) {
return size(); return size();
} }
@@ -303,116 +319,119 @@ public:
return size(); // base case return size(); // base case
} }
// Manipulation ========================================================================================================
///
/// \brief Resize the string, filling additional bytes with `'\0'`
/// \param n the new size of the string
constexpr void resize(size_t n) {
size_t i = size();
_str.reallocate(n + 1);
if (n > i) fennec::wmemset(_str.data() + i, L'\0', n - i);
}
///
/// \brief Copy Assignment Operator
/// \param str the string to copy
/// \returns a reference to `this`
constexpr wstring& operator=(const wcstring& str) {
if (str.empty()) {
_str.deallocate();
return *this;
}
if (str.size() > size()) resize(str.size());
fennec::wmemcpy(_str.data(), str, str.size());
_str[str.size()] = L'\0';
return *this;
}
///
/// \brief Copy Assignment Operator
/// \param str the string to copy
/// \returns a reference to `this`
constexpr wstring& operator=(const wstring& str) {
if (str.size() > size()) resize(str.size());
fennec::wmemcpy(_str.data(), str, str.size());
_str[str.size()] = '\0';
return *this;
}
///
/// \brief Move Assignment Operator
/// \param str the string to move
/// \returns a reference to `this`
constexpr wstring& operator=(wstring&& str) noexcept {
_str = fennec::move(str._str);
return *this;
}
/// ///
/// \brief Retrieve a substring of a string /// \brief Retrieve a substring of a string
/// \param i the start index /// \param i the start index
/// \param n the number of characters /// \param n the number of wchar_tacters
/// \return /// \return
constexpr wstring substring(size_t i, size_t n = npos) const { constexpr _wstring substring(size_t i, size_t n = npos) const {
if (i >= size()) { if (i >= size()) {
return wstring(""); return _wstring("");
} }
n = min(n, size() - i); n = fennec::min(n, size() - i);
return wstring(_str.data() + i, n); _wstring res;
} res._str.callocate(n + 1);
fennec::wmemcpy(res.data(), _str + i, n);
///
/// \brief Returns a string with `c` appended to it
/// \param c
/// \returns
constexpr wstring operator+(wchar_t c) const {
// Copy contents with one additional byte.
wstring res(_str, _str.size());
res[size()] = c; // Set the last character to c
return res; return res;
} }
constexpr wstring operator+(const wcstring& str) const {
wstring res(size() + str.size()); // Make a new string with the size of this + str
fennec::wmemcpy(&res[0], _str.data(), size()); // Copy the contents of this // Modifiers ===========================================================================================================
fennec::wmemcpy(&res[size()], str, str.size()); // Append the contents of str
constexpr void resize(size_t n) {
_str.creallocate(n + 1);
_str[size()] = '\0';
}
constexpr _wstring operator+(wchar_t c) const {
if (_str == nullptr) {
return _wstring(1, c);
}
_wstring res;
res._str.callocate(capacity() + 1);
fennec::wmemcpy(res.data(), _str, size());
res[size()] = c;
return res; return res;
} }
constexpr wstring operator+(const wstring& str) const { friend constexpr _wstring operator+(wchar_t c, const _wstring& str) {
wstring res(size() + str.size()); // Make a new string with the size of this + str _wstring res(1, c);
fennec::wmemcpy(&res[0], _str.data(), size()); // Copy the contents of this return res += str;
fennec::wmemcpy(&res[size()], str, str.size()); // Append the contents of str }
constexpr _wstring operator+(const wcstring& cstr) const {
if (_str == nullptr) {
return _wstring(cstr);
}
_wstring res;
res._str.callocate(size() + cstr.size() + 1);
fennec::wmemcpy(res.data(), _str, size());
fennec::wmemcpy(res.data() + size(), cstr, cstr.size());
return res; return res;
} }
constexpr wstring& operator+=(wchar_t c) { constexpr _wstring operator+(const _wstring& str) const {
size_t x = size(); if (_str == nullptr) {
resize(x + 1); return _wstring(str);
_str[x] = c; }
if (str.data() == nullptr) {
return _wstring(*this);
}
_wstring res;
res._str.callocate(size() + str.size() + 1);
fennec::wmemcpy(res.data(), _str, size());
fennec::wmemcpy(res.data() + size(), str.data(), str.size());
return res;
}
constexpr _wstring& operator+=(wchar_t c) {
if (_str == nullptr) {
_str.callocate(2);
_str[0] = c;
return *this;
}
_str.creallocate(capacity() + 1);
_str[size() - 1] = c;
return *this; return *this;
} }
constexpr wstring& operator+=(const wcstring& str) { constexpr _wstring& operator+=(const wcstring& cstr) {
size_t x = size(); if (_str == nullptr) {
resize(x + str.size()); return *this = cstr;
fennec::wmemcpy(&_str[x], str, str.size()); }
size_t middle = size();
_str.creallocate(middle + cstr.size() + 1);
fennec::wmemcpy(_str + middle, cstr, cstr.size());
return *this; return *this;
} }
constexpr wstring& operator+=(const wstring& str) { constexpr _wstring& operator+=(const _wstring& str) {
size_t x = size(); if (_str == nullptr) {
resize(x + str.size()); return *this = str;
fennec::wmemcpy(&_str[x], str, str.size()); }
if (str.data() == nullptr) {
return *this;
}
size_t middle = size();
_str.creallocate(middle + str.size() + 1);
fennec::wmemcpy(_str + middle, str.data(), str.size());
return *this; return *this;
} }
private: private:
alloc_t _str; alloc_t _str;
}; };
template<>
struct hash<wstring> : hash<byte_array> {
constexpr size_t operator()(const string& str) const {
return hash<byte_array>::operator()(byte_array(str.data(), str.size()));
}
};
} }
#endif // FENNEC_LANGPROC_wstringS_wstring_H #endif // FENNEC_LANGPROC_wstringS_WSTRING_H

View File

@@ -491,13 +491,7 @@ public:
/// If there is already an allocated block of memory, the previous allocation is released. /// If there is already an allocated block of memory, the previous allocation is released.
/// \param n The number of elements of type `T` to allocate for /// \param n The number of elements of type `T` to allocate for
constexpr void callocate(size_t n, align_t align = zero<align_t>()) noexcept { constexpr void callocate(size_t n, align_t align = zero<align_t>()) noexcept {
deallocate(); allocate(n, align);
if (align != zero<align_t>()) {
_data = _alloc.allocate(_capacity = n, _alignment = align);
} else {
_data = _alloc.allocate(_capacity = n);
}
fennec::memset(static_cast<void*>(_data), 0, _capacity * sizeof(T)); fennec::memset(static_cast<void*>(_data), 0, _capacity * sizeof(T));
} }
@@ -523,12 +517,15 @@ public:
constexpr void reallocate(size_t n, align_t align = zero<align_t>()) noexcept { constexpr void reallocate(size_t n, align_t align = zero<align_t>()) noexcept {
if (_data == nullptr) { if (_data == nullptr) {
allocate(n, align); allocate(n, align);
return;
} }
value_t* old = _data; value_t* old = _data; size_t old_cap = _capacity;
_data = nullptr; _data = nullptr;
allocate(n, align); allocate(n, align);
fennec::memmove(static_cast<void*>(_data), old, min(_capacity, n) * sizeof(T));
fennec::memmove(static_cast<void*>(_data), old, min(_capacity, old_cap) * sizeof(T));
_alloc.deallocate(old); _alloc.deallocate(old);
_capacity = n; _capacity = n;
} }
@@ -539,12 +536,19 @@ public:
constexpr void creallocate(size_t n, align_t align = zero<align_t>()) noexcept { constexpr void creallocate(size_t n, align_t align = zero<align_t>()) noexcept {
if (_data == nullptr) { if (_data == nullptr) {
callocate(n, align); callocate(n, align);
return;
} }
value_t* old = _data; value_t* old = _data; size_t old_cap = _capacity;
_data = nullptr; _data = nullptr;
callocate(n, align); allocate(n, align);
fennec::memmove(static_cast<void*>(_data), old, min(_capacity, n) * sizeof(T));
fennec::memmove(static_cast<void*>(_data), old, min(_capacity, old_cap) * sizeof(T));
if (_capacity > old_cap) {
fennec::memset(static_cast<void*>(_data + old_cap), 0, _capacity - old_cap);
}
_alloc.deallocate(old); _alloc.deallocate(old);
_capacity = n; _capacity = n;
} }
@@ -557,14 +561,17 @@ public:
return _data[i]; return _data[i];
} }
constexpr value_t operator[](size_t i) const requires is_fundamental_v<value_t> { constexpr const value_t& operator[](size_t i) const {
assertd(i < capacity(), "Array Out of Bounds"); assertd(i < capacity(), "Array Out of Bounds");
return _data[i]; return _data[i];
} }
constexpr const value_t& operator[](size_t i) const { constexpr operator value_t*() {
assertd(i < capacity(), "Array Out of Bounds"); return _data;
return _data[i]; }
constexpr operator const value_t*() const {
return _data;
} }
value_t* begin() { value_t* begin() {

View File

@@ -27,7 +27,7 @@
namespace fennec namespace fennec
{ {
class display class display : public typed<display>
{ {
public: public:
struct pixel_format { struct pixel_format {
@@ -42,7 +42,7 @@ public:
virtual bool connected() const = 0; virtual bool connected() const = 0;
virtual ~display(); virtual ~display();
virtual window* create_window() = 0; virtual window* create_window(window* parent) = 0;
const pixel_format& get_color_format() const { const pixel_format& get_color_format() const {
return _config.format; return _config.format;
@@ -55,7 +55,6 @@ public:
gfxcontext* get_context() { return _context; } gfxcontext* get_context() { return _context; }
const string name; const string name;
const uint64_t uuid;
protected: protected:
platform* _platform; platform* _platform;
@@ -63,9 +62,9 @@ protected:
config _config; config _config;
template<typename DisplayT> template<typename DisplayT>
explicit display(platform* platform, const cstring& name, DisplayT*) explicit display(platform* platform, const cstring& name, DisplayT* type)
: name(name) : typed(type)
, uuid(typeuuid<DisplayT>()) , name(name)
, _platform(platform) , _platform(platform)
, _context(nullptr) , _context(nullptr)
, _config { , _config {

View File

@@ -22,33 +22,39 @@
#include <fennec/langproc/strings/string.h> #include <fennec/langproc/strings/string.h>
#include <fennec/lang/typeuuid.h> #include <fennec/lang/typeuuid.h>
#include <fennec/platform/interface/fwd.h> #include <fennec/platform/interface/fwd.h>
#include <fennec/platform/interface/window.h>
namespace fennec namespace fennec
{ {
class gfxcontext { class gfxcontext : public typed<gfxcontext> {
public: public:
const string name; const string name;
const uint64_t uuid;
virtual bool connected() = 0; virtual bool connected() = 0;
virtual const cstring& get_name() = 0;
virtual int32_t get_version_major() = 0; virtual int32_t get_version_major() = 0;
virtual int32_t get_version_minor() = 0; virtual int32_t get_version_minor() = 0;
virtual int32_t get_context_version() = 0; virtual int32_t get_version() = 0;
virtual const cstring& get_context_name() = 0;
virtual bool check_extension(const cstring& ext) = 0; virtual bool check_extension(const cstring& ext) = 0;
virtual void make_current(gfxsurface* surface) = 0; virtual void make_current(gfxsurface* surface) = 0;
virtual gfxsurface* create_surface(window* window) = 0;
virtual ~gfxcontext() = default; virtual ~gfxcontext() = default;
display* get_display() {
return _display;
}
protected: protected:
display* _display; display* _display;
template<typename ContextT> template<typename ContextT>
gfxcontext(display* display, const cstring& name, ContextT*) gfxcontext(display* display, const cstring& name, ContextT* type)
: name(name) : typed(type)
, uuid(typeuuid<ContextT>()) , name(name)
, _display(display) { , _display(display) {
} }
}; };

View File

@@ -0,0 +1,76 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file gfxsurface.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_INTERFACE_GFXSURFACE_H
#define FENNEC_PLATFORM_INTERFACE_GFXSURFACE_H
#include <fennec/lang/types.h>
#include <fennec/lang/typeuuid.h>
#include <fennec/platform/interface/fwd.h>
#include <fennec/platform/interface/window.h>
namespace fennec
{
class gfxsurface : public typed<gfxsurface> {
public:
virtual ~gfxsurface() = default;
virtual void resize(size_t width, size_t height) {
_width = width;
_height = height;
}
gfxcontext* get_context() {
return _context;
}
window* get_window() {
return _window;
}
protected:
gfxcontext* _context;
window* _window;
size_t _width, _height;
template<typename SurfaceT>
gfxsurface(gfxcontext* ctx, window* window, SurfaceT* type)
: typed(type)
, _context(ctx)
, _window(window)
, _width(window->get_width()), _height(window->get_height()) {
}
};
}
#endif // FENNEC_PLATFORM_INTERFACE_GFXSURFACE_H

View File

@@ -59,13 +59,12 @@
namespace fennec namespace fennec
{ {
class platform { class platform : public typed<platform> {
public: public:
using shared_object = struct shared_object; using shared_object = struct shared_object;
using symbol = void*; using symbol = void*;
const string name; const string name;
const uint64_t uuid;
virtual ~platform() = default; virtual ~platform() = default;
@@ -81,9 +80,9 @@ public:
protected: protected:
template<typename PlatformT> template<typename PlatformT>
explicit platform(const cstring& name, PlatformT*) explicit platform(const cstring& name, PlatformT* type)
: name(name) : typed(type)
, uuid(typeuuid<PlatformT>()) { , name(name) {
auto& globals = _get_globals(); auto& globals = _get_globals();
assertf(globals.singleton == nullptr, "Conflicting Platform Definitions."); assertf(globals.singleton == nullptr, "Conflicting Platform Definitions.");
globals.singleton = this; globals.singleton = this;

View File

@@ -22,6 +22,7 @@
#include <fennec/containers/optional.h> #include <fennec/containers/optional.h>
#include <fennec/langproc/strings/string.h> #include <fennec/langproc/strings/string.h>
#include <fennec/platform/interface/fwd.h> #include <fennec/platform/interface/fwd.h>
#include <fennec/platform/linux/wayland/display.h>
namespace fennec namespace fennec
{ {
@@ -29,7 +30,7 @@ namespace fennec
/// ///
/// \brief interface for handling windows /// \brief interface for handling windows
/// \details the interface makes no guarantees about the bit-depth and is completely dependent on the implementation. /// \details the interface makes no guarantees about the bit-depth and is completely dependent on the implementation.
class window { class window : public typed<window> {
public: public:
enum class fullscreen_mode { enum class fullscreen_mode {
windowed = 0, windowed = 0,
@@ -53,6 +54,8 @@ public:
fullscreen_mode fullscreen; fullscreen_mode fullscreen;
}; };
virtual ~window() = default;
virtual bool running() = 0; virtual bool running() = 0;
virtual void configure(const config& config) = 0; virtual void configure(const config& config) = 0;
virtual bool initialize(bool modal) = 0; virtual bool initialize(bool modal) = 0;
@@ -63,7 +66,7 @@ public:
virtual bool set_width(size_t w) = 0; virtual bool set_width(size_t w) = 0;
virtual bool set_height(size_t h) = 0; virtual bool set_height(size_t h) = 0;
virtual bool set_size(size_t w, 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_fullscreen_mode(fullscreen_mode mode) = 0;
@@ -73,6 +76,8 @@ public:
virtual bool grab_mouse(bool e) = 0; virtual bool grab_mouse(bool e) = 0;
virtual bool block_screensaver(bool e) = 0; virtual bool block_screensaver(bool e) = 0;
virtual struct wl_surface* get_native_handle() = 0;
bool is_child() const { bool is_child() const {
if (not _config) return false; if (not _config) return false;
return _config->flags & flags_child; return _config->flags & flags_child;
@@ -91,9 +96,13 @@ public:
return _display; return _display;
} }
const config& get_config() const {
return *_config;
}
const string& get_title() const { const string& get_title() const {
static const string _null = { "null" }; static const string _null{"null"};
if (not _config) return _null; if (not _config) return _null;
return _config->title; return _config->title;
} }
@@ -137,13 +146,20 @@ public:
} }
protected: protected:
virtual ~window() = default; template<typename TypeT>
window(display* display, window* parent); window(display* display, window* parent, TypeT* type)
: typed(type)
, _display(display)
, _parent(parent)
, _surface(nullptr) {
}
display* _display; display* _display;
window* _parent; window* _parent;
optional<config> _config; optional<config> _config;
gfxsurface* _context; gfxsurface* _surface;
private:
private: private:
}; };

View File

@@ -20,7 +20,7 @@
#define FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H #define FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H
#include <fennec/platform/interface/display.h> #include <fennec/platform/interface/display.h>
#include <fennec/platform/linux/wayland/lib/fwd.h> #include <fennec/platform/linux/wayland/lib/wayland.h>
namespace fennec namespace fennec
{ {
@@ -33,13 +33,28 @@ public:
bool connected() const override; bool connected() const override;
void* get_native_handle() override { return _handle; } void* get_native_handle() override { return _handle; }
window* create_window() override; 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: private:
wl_display* _handle; wl_display* _handle;
wl_registry* _registry; wl_registry* _registry;
wl_compositor* _compositor; wl_compositor* _compositor;
wl_shell* _shell; //xdg_wm_base* _shell;
wl_seat* _seat; wl_seat* _seat;
wl_shm* _shm; wl_shm* _shm;
bool _fifo; bool _fifo;

View File

@@ -1,86 +0,0 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_LIB_FWD_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_LIB_FWD_H
/*
* Copyright © 2008 Kristian Høgsberg
*
* 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 <fennec/lang/types.h>
#include <stdarg.h>
struct wl_object;
struct wl_proxy;
struct wl_display;
struct wl_event_queue;
struct wl_buffer;
struct wl_callback;
struct wl_compositor;
struct wl_data_device;
struct wl_data_device_manager;
struct wl_data_offer;
struct wl_data_source;
struct wl_keyboard;
struct wl_output;
struct wl_pointer;
struct wl_region;
struct wl_registry;
struct wl_seat;
struct wl_shell;
struct wl_shell_surface;
struct wl_shm;
struct wl_shm_pool;
struct wl_subcompositor;
struct wl_subsurface;
struct wl_surface;
struct wl_touch;
struct wl_egl_window;
struct wl_surface;
typedef int32_t wl_fixed_t;
#define WL_PRINTF(x, y) __attribute__((__format__(__printf__, x, y)))
typedef void (*wl_log_func_t)(const char *fmt, va_list args) WL_PRINTF(1, 0);
#define WL_MARSHAL_FLAG_DESTROY (1 << 0)
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_LIB_FWD_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

View File

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

View File

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

View File

@@ -17,32 +17,6 @@
// ===================================================================================================================== // =====================================================================================================================
#include <fennec/lang/types.h> #include <fennec/lang/types.h>
#include <fennec/platform/linux/wayland/lib/fwd.h>
/*
* Copyright © 2008 Kristian Høgsberg
*
* 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.
*/
#ifndef FENNEC_LIB #ifndef FENNEC_LIB
#define FENNEC_LIB(...) #define FENNEC_LIB(...)
@@ -60,7 +34,7 @@
FENNEC_LIB(WAYLAND); FENNEC_LIB(WAYLAND);
FENNEC_SYMBOL(void, wl_proxy_marshal, struct wl_proxy*, uint32_t, ...); FENNEC_SYMBOL(void, wl_proxy_marshal, struct wl_proxy*, uint32_t, ...);
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_flags, struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, uint32_t flags, ...); 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(struct wl_proxy*, wl_proxy_create, struct wl_proxy*, const struct wl_interface*);
FENNEC_SYMBOL(void, wl_proxy_destroy, struct wl_proxy*); FENNEC_SYMBOL(void, wl_proxy_destroy, struct wl_proxy*);
FENNEC_SYMBOL(int, wl_proxy_add_listener, struct wl_proxy*, void (**)(void), void*); FENNEC_SYMBOL(int, wl_proxy_add_listener, struct wl_proxy*, void (**)(void), void*);
@@ -72,6 +46,11 @@ FENNEC_SYMBOL(const char*, wl_proxy_get_class, st
FENNEC_SYMBOL(void, wl_proxy_set_queue, struct wl_proxy*, struct wl_event_queue*); 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_create_wrapper, void*);
FENNEC_SYMBOL(void, wl_proxy_wrapper_destroy, 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, const char*);
FENNEC_SYMBOL(struct wl_display*, wl_display_connect_to_fd, int); FENNEC_SYMBOL(struct wl_display*, wl_display_connect_to_fd, int);
FENNEC_SYMBOL(void, wl_display_disconnect, struct wl_display*); FENNEC_SYMBOL(void, wl_display_disconnect, struct wl_display*);
@@ -88,6 +67,7 @@ FENNEC_SYMBOL(int, wl_display_get_error, st
FENNEC_SYMBOL(int, wl_display_flush, struct wl_display*); FENNEC_SYMBOL(int, wl_display_flush, struct wl_display*);
FENNEC_SYMBOL(int, wl_display_roundtrip, 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(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_event_queue_destroy, struct wl_event_queue*);
FENNEC_SYMBOL(void, wl_log_set_handler_client, wl_log_func_t); 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_init, struct wl_list*);
@@ -96,10 +76,6 @@ FENNEC_SYMBOL(void, wl_list_remove, st
FENNEC_SYMBOL(int, wl_list_length, const 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(int, wl_list_empty, const struct wl_list*);
FENNEC_SYMBOL(void, wl_list_insert_list, struct wl_list*, struct wl_list*); FENNEC_SYMBOL(void, wl_list_insert_list, struct wl_list*, struct wl_list*);
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_constructor, struct wl_proxy*, uint32_t opcode, const struct wl_interface*interface, ...);
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_constructor_versioned, struct wl_proxy*proxy, uint32_t opcode, const struct wl_interface*interface, uint32_t version, ...);
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_GLOBAL(const struct wl_interface, wl_display_interface); 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_registry_interface);

File diff suppressed because it is too large Load Diff

View File

@@ -1,198 +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_UTIL_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_UTIL_H
/*
* Copyright © 2008 Kristian Høgsberg
*
* 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 <stddef.h>
#include <inttypes.h>
#include <stdarg.h>
#if defined(__GNUC__) && __GNUC__ >= 4
#define WL_EXPORT __attribute__ ((visibility("default")))
#else
#define WL_EXPORT
#endif
#if __STDC_VERSION__ >= 202311L
#define WL_DEPRECATED [[deprecated]]
#elif defined(__GNUC__) && __GNUC__ >= 4
#define WL_DEPRECATED __attribute__ ((deprecated))
#else
#define WL_DEPRECATED
#endif
#if defined(__GNUC__) && __GNUC__ >= 4
#define WL_PRINTF(x, y) __attribute__((__format__(__printf__, x, y)))
#else
#define WL_PRINTF(x, y)
#endif
#if __STDC_VERSION__ >= 202311L
#define WL_TYPEOF(expr) typeof(expr)
#else
#define WL_TYPEOF(expr) __typeof__(expr)
#endif
struct wl_message {
const char *name;
const char *signature;
const struct wl_interface **types;
};
struct wl_interface {
const char *name;
int version;
int method_count;
const struct wl_message *methods;
int event_count;
const struct wl_message *events;
};
struct wl_list {
struct wl_list *prev;
struct wl_list *next;
};
#define wl_container_of(ptr, sample, member) \
(WL_TYPEOF(sample))((char *)(ptr) - \
offsetof(WL_TYPEOF(*sample), member))
#define wl_list_for_each(pos, head, member) \
for (pos = wl_container_of((head)->next, pos, member); \
&pos->member != (head); \
pos = wl_container_of(pos->member.next, pos, member))
#define wl_list_for_each_safe(pos, tmp, head, member) \
for (pos = wl_container_of((head)->next, pos, member), \
tmp = wl_container_of((pos)->member.next, tmp, member); \
&pos->member != (head); \
pos = tmp, \
tmp = wl_container_of(pos->member.next, tmp, member))
#define wl_list_for_each_reverse(pos, head, member) \
for (pos = wl_container_of((head)->prev, pos, member); \
&pos->member != (head); \
pos = wl_container_of(pos->member.prev, pos, member))
#define wl_list_for_each_reverse_safe(pos, tmp, head, member) \
for (pos = wl_container_of((head)->prev, pos, member), \
tmp = wl_container_of((pos)->member.prev, tmp, member); \
&pos->member != (head); \
pos = tmp, \
tmp = wl_container_of(pos->member.prev, tmp, member))
struct wl_array {
size_t size;
size_t alloc;
void *data;
};
void
wl_array_init(struct wl_array *array);
void
wl_array_release(struct wl_array *array);
void *
wl_array_add(struct wl_array *array, size_t size);
int
wl_array_copy(struct wl_array *array, struct wl_array *source);
#define wl_array_for_each(pos, array) \
for (pos = (array)->data; \
(array)->size != 0 && \
(const char *) pos < ((const char *) (array)->data + (array)->size); \
(pos)++)
typedef int32_t wl_fixed_t;
static inline double
wl_fixed_to_double(wl_fixed_t f)
{
return f / 256.0;
}
static inline wl_fixed_t
wl_fixed_from_double(double d)
{
return (wl_fixed_t) (d * 256.0);
}
static inline int
wl_fixed_to_int(wl_fixed_t f)
{
return f / 256;
}
static inline wl_fixed_t
wl_fixed_from_int(int i)
{
return i * 256;
}
union wl_argument {
int32_t i;
uint32_t u;
wl_fixed_t f;
const char *s;
struct wl_object *o;
uint32_t n;
struct wl_array *a;
int32_t h;
};
typedef int (*wl_dispatcher_func_t)(const void *user_data, void *target,
uint32_t opcode, const struct wl_message *msg,
union wl_argument *args);
typedef void (*wl_log_func_t)(const char *fmt, va_list args) WL_PRINTF(1, 0);
enum wl_iterator_result {
WL_ITERATOR_STOP,
WL_ITERATOR_CONTINUE
};
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_UTIL_H

View File

@@ -0,0 +1,98 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_CLIENT_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_CLIENT_H
#include <wayland-client-core.h>
#define FENNEC_LIB(name) extern "C" bool FENNEC_HAS_LIB_##name;
#define FENNEC_SYMBOL(ret, fn, ...) using WAYLAND_sym_##fn = ret(*)(__VA_ARGS__); \
extern "C" WAYLAND_sym_##fn WAYLAND_##fn;
#define FENNEC_GLOBAL(type, name) extern "C" type* WAYLAND_##name;
#include <fennec/platform/linux/wayland/lib/sym.h>
#define wl_proxy_marshal WAYLAND_wl_proxy_marshal
#define wl_proxy_marshal_flags WAYLAND_wl_proxy_marshal_flags
#define wl_proxy_create WAYLAND_wl_proxy_create
#define wl_proxy_destroy WAYLAND_wl_proxy_destroy
#define wl_proxy_add_listener WAYLAND_wl_proxy_add_listener
#define wl_proxy_set_user_data WAYLAND_wl_proxy_set_user_data
#define wl_proxy_get_user_data WAYLAND_wl_proxy_get_user_data
#define wl_proxy_get_version WAYLAND_wl_proxy_get_version
#define wl_proxy_get_id WAYLAND_wl_proxy_get_id
#define wl_proxy_get_class WAYLAND_wl_proxy_get_class
#define wl_proxy_set_queue WAYLAND_wl_proxy_set_queue
#define wl_proxy_create_wrapper WAYLAND_wl_proxy_create_wrapper
#define wl_proxy_wrapper_destroy WAYLAND_wl_proxy_wrapper_destroy
#define wl_proxy_marshal_constructor WAYLAND_wl_proxy_marshal_constructor
#define wl_proxy_marshal_constructor_versioned WAYLAND_wl_proxy_marshal_constructor_versioned
#define wl_proxy_set_tag WAYLAND_wl_proxy_set_tag
#define wl_proxy_get_tag WAYLAND_wl_proxy_get_tag
#define wl_event_queue_destroy WAYLAND_wl_event_queue_destroy
#define wl_log_set_handler_client WAYLAND_wl_log_set_handler_client
#define wl_list_init WAYLAND_wl_list_init
#define wl_list_insert WAYLAND_wl_list_insert
#define wl_list_remove WAYLAND_wl_list_remove
#define wl_list_length WAYLAND_wl_list_length
#define wl_list_empty WAYLAND_wl_list_empty
#define wl_list_insert_list WAYLAND_wl_list_insert_list
#define wl_display_connect WAYLAND_wl_display_connect
#define wl_display_connect_to_fd WAYLAND_wl_display_connect_to_fd
#define wl_display_reconnect WAYLAND_wl_display_reconnect
#define wl_display_disconnect WAYLAND_wl_display_disconnect
#define wl_display_get_fd WAYLAND_wl_display_get_fd
#define wl_display_dispatch WAYLAND_wl_display_dispatch
#define wl_display_dispatch_queue WAYLAND_wl_display_dispatch_queue
#define wl_display_dispatch_queue_pending WAYLAND_wl_display_dispatch_queue_pending
#define wl_display_dispatch_pending WAYLAND_wl_display_dispatch_pending
#define wl_display_prepare_read WAYLAND_wl_display_prepare_read
#define wl_display_prepare_read_queue WAYLAND_wl_display_prepare_read_queue
#define wl_display_read_events WAYLAND_wl_display_read_events
#define wl_display_cancel_read WAYLAND_wl_display_cancel_read
#define wl_display_get_error WAYLAND_wl_display_get_error
#define wl_display_flush WAYLAND_wl_display_flush
#define wl_display_roundtrip WAYLAND_wl_display_roundtrip
#define wl_display_create_queue WAYLAND_wl_display_create_queue
#define wl_seat_interface *WAYLAND_wl_seat_interface
#define wl_surface_interface *WAYLAND_wl_surface_interface
#define wl_shm_pool_interface *WAYLAND_wl_shm_pool_interface
#define wl_buffer_interface *WAYLAND_wl_buffer_interface
#define wl_registry_interface *WAYLAND_wl_registry_interface
#define wl_region_interface *WAYLAND_wl_region_interface
#define wl_pointer_interface *WAYLAND_wl_pointer_interface
#define wl_keyboard_interface *WAYLAND_wl_keyboard_interface
#define wl_compositor_interface *WAYLAND_wl_compositor_interface
#define wl_output_interface *WAYLAND_wl_output_interface
#define wl_shm_interface *WAYLAND_wl_shm_interface
#define wl_data_device_interface *WAYLAND_wl_data_device_interface
#define wl_data_offer_interface *WAYLAND_wl_data_offer_interface
#define wl_data_source_interface *WAYLAND_wl_data_source_interface
#define wl_data_device_manager_interface *WAYLAND_wl_data_device_manager_interface
#define wl_egl_window_create WAYLAND_wl_egl_window_create
#define wl_egl_window_destroy WAYLAND_wl_egl_window_destroy
#define wl_egl_window_resize WAYLAND_wl_egl_window_resize
#define wl_egl_window_get_attached_size WAYLAND_wl_egl_window_get_attached_size
#include <fennec/platform/linux/wayland/lib/headers/wayland-client-protocols.h>
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_CLIENT_H

View File

@@ -0,0 +1,83 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file window.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H
#include <fennec/platform/interface/window.h>
#include <fennec/platform/linux/wayland/display.h>
namespace fennec
{
class wayland_window : public window {
public:
bool running() override;
void configure(const config& config) override;
bool initialize(bool modal) override;
bool shutdown() override;
bool set_title(const cstring& title) override;
bool set_title(const string& title) override;
bool set_width(size_t w) override;
bool set_height(size_t h) override;
bool resize(size_t w, size_t h) override;
bool set_resizable(bool e) override;
bool set_fullscreen_mode(fullscreen_mode mode) override;
bool grab_keyboard(bool e) override;
bool grab_mouse(bool e) override;
bool block_screensaver(bool e) override;
wayland_window(wayland_display* display, wayland_window* parent);
~wayland_window() override;
struct wl_surface* get_native_handle() override {
return _handle;
}
private:
wl_surface* _handle;
wl_shell_surface* _shell;
size_t _nfs_width, _nfs_height;
static void listen_ping(void*, wl_shell_surface*, uint32_t);
static void listen_configure(void*, wl_shell_surface*, uint32_t, int32_t, int32_t);
static void listen_popup_done(void*, wl_shell_surface*);
};
}
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H

View File

@@ -1,215 +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_FWD_H
#define FENNEC_PLATFORM_LINUX_XKB_LIB_FWD_H
#include <fennec/lang/types.h>
/*
* 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>
*/
struct xkb_context;
struct xkb_keymap;
struct xkb_state;
struct xkb_rule_names;
typedef uint32_t xkb_keycode_t;
typedef uint32_t xkb_keysym_t;
typedef uint32_t xkb_layout_index_t;
typedef uint32_t xkb_layout_mask_t;
typedef uint32_t xkb_level_index_t;
typedef uint32_t xkb_mod_index_t;
typedef uint32_t xkb_mod_mask_t;
typedef uint32_t xkb_led_index_t;
typedef uint32_t xkb_led_mask_t;
/**
* The iterator used by xkb_keymap_key_for_each().
*
* @sa xkb_keymap_key_for_each
* @memberof xkb_keymap
* @since 0.3.1
*/
typedef void
(*xkb_keymap_key_iter_t)(struct xkb_keymap *keymap, xkb_keycode_t key,
void *data);
/** Flags for xkb_keysym_from_name(). */
enum xkb_keysym_flags {
/** Do not apply any flags. */
XKB_KEYSYM_NO_FLAGS = 0,
/** Find keysym by case-insensitive search. */
XKB_KEYSYM_CASE_INSENSITIVE = (1 << 0)
};
/** Flags for context creation. */
enum xkb_context_flags {
/** Do not apply any context flags. */
XKB_CONTEXT_NO_FLAGS = 0,
/** Create this context with an empty include path. */
XKB_CONTEXT_NO_DEFAULT_INCLUDES = (1 << 0),
/**
* Don't take RMLVO names from the environment.
*
* @since 0.3.0
*/
XKB_CONTEXT_NO_ENVIRONMENT_NAMES = (1 << 1),
/**
* Disable the use of secure_getenv for this context, so that privileged
* processes can use environment variables. Client uses at their own risk.
*
* @since 1.5.0
*/
XKB_CONTEXT_NO_SECURE_GETENV = (1 << 2)
};
/** Specifies a logging level. */
enum xkb_log_level {
XKB_LOG_LEVEL_CRITICAL = 10, /**< Log critical internal errors only. */
XKB_LOG_LEVEL_ERROR = 20, /**< Log all errors. */
XKB_LOG_LEVEL_WARNING = 30, /**< Log warnings and errors. */
XKB_LOG_LEVEL_INFO = 40, /**< Log information, warnings, and errors. */
XKB_LOG_LEVEL_DEBUG = 50 /**< Log everything. */
};
/** Flags for keymap compilation. */
enum xkb_keymap_compile_flags {
/** Do not apply any flags. */
XKB_KEYMAP_COMPILE_NO_FLAGS = 0
};
/** The possible keymap formats. */
enum xkb_keymap_format {
/** The current/classic XKB text format, as generated by xkbcomp -xkb. */
XKB_KEYMAP_FORMAT_TEXT_V1 = 1
};
/** Specifies the direction of the key (press / release). */
enum xkb_key_direction {
XKB_KEY_UP, /**< The key was released. */
XKB_KEY_DOWN /**< The key was pressed. */
};
/**
* Modifier and layout types for state objects. This enum is bitmaskable,
* e.g. (XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED) is valid to
* exclude locked modifiers.
*
* In XKB, the DEPRESSED components are also known as 'base'.
*/
enum xkb_state_component {
/** Depressed modifiers, i.e. a key is physically holding them. */
XKB_STATE_MODS_DEPRESSED = (1 << 0),
/** Latched modifiers, i.e. will be unset after the next non-modifier
* key press. */
XKB_STATE_MODS_LATCHED = (1 << 1),
/** Locked modifiers, i.e. will be unset after the key provoking the
* lock has been pressed again. */
XKB_STATE_MODS_LOCKED = (1 << 2),
/** Effective modifiers, i.e. currently active and affect key
* processing (derived from the other state components).
* Use this unless you explicitly care how the state came about. */
XKB_STATE_MODS_EFFECTIVE = (1 << 3),
/** Depressed layout, i.e. a key is physically holding it. */
XKB_STATE_LAYOUT_DEPRESSED = (1 << 4),
/** Latched layout, i.e. will be unset after the next non-modifier
* key press. */
XKB_STATE_LAYOUT_LATCHED = (1 << 5),
/** Locked layout, i.e. will be unset after the key provoking the lock
* has been pressed again. */
XKB_STATE_LAYOUT_LOCKED = (1 << 6),
/** Effective layout, i.e. currently active and affects key processing
* (derived from the other state components).
* Use this unless you explicitly care how the state came about. */
XKB_STATE_LAYOUT_EFFECTIVE = (1 << 7),
/** LEDs (derived from the other state components). */
XKB_STATE_LEDS = (1 << 8)
};
/**
* Match flags for xkb_state_mod_indices_are_active() and
* xkb_state_mod_names_are_active(), specifying the conditions for a
* successful match. XKB_STATE_MATCH_NON_EXCLUSIVE is bitmaskable with
* the other modes.
*/
enum xkb_state_match {
/** Returns true if any of the modifiers are active. */
XKB_STATE_MATCH_ANY = (1 << 0),
/** Returns true if all of the modifiers are active. */
XKB_STATE_MATCH_ALL = (1 << 1),
/** Makes matching non-exclusive, i.e. will not return false if a
* modifier not specified in the arguments is active. */
XKB_STATE_MATCH_NON_EXCLUSIVE = (1 << 16)
};
enum xkb_consumed_mode {
/**
* This is the mode defined in the XKB specification and used by libX11.
*
* A modifier is consumed if and only if it *may affect* key translation.
*
* For example, if `Control+Alt+<Backspace>` produces some assigned keysym,
* then when pressing just `<Backspace>`, `Control` and `Alt` are consumed,
* even though they are not active, since if they *were* active they would
* have affected key translation.
*/
XKB_CONSUMED_MODE_XKB,
/**
* This is the mode used by the GTK+ toolkit.
*
* The mode consists of the following two independent heuristics:
*
* - The currently active set of modifiers, excluding modifiers which do
* not affect the key (as described for @ref XKB_CONSUMED_MODE_XKB), are
* considered consumed, if the keysyms produced when all of them are
* active are different from the keysyms produced when no modifiers are
* active.
*
* - A single modifier is considered consumed if the keysyms produced for
* the key when it is the only active modifier are different from the
* keysyms produced when no modifiers are active.
*/
XKB_CONSUMED_MODE_GTK
};
#endif // FENNEC_PLATFORM_LINUX_XKB_LIB_FWD_H

View File

@@ -44,7 +44,6 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <fennec/platform/linux/xkb/lib/fwd.h>
#ifndef FENNEC_LIB #ifndef FENNEC_LIB
#define FENNEC_LIB(...) #define FENNEC_LIB(...)
@@ -60,82 +59,85 @@
FENNEC_LIB(XKB); FENNEC_LIB(XKB);
FENNEC_SYMBOL(int, xkb_keysym_get_name, xkb_keysym_t keysym, char *buffer, size_t size); FENNEC_SYMBOL(int, xkb_keysym_get_name, xkb_keysym_t, char*, size_t);
FENNEC_SYMBOL(xkb_keysym_t, xkb_keysym_from_name, const char *name, enum xkb_keysym_flags flags); 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 keysym, char *buffer, size_t size); FENNEC_SYMBOL(int, xkb_keysym_to_utf8, xkb_keysym_t, char*, size_t);
FENNEC_SYMBOL(uint32_t, xkb_keysym_to_utf32, xkb_keysym_t keysym); FENNEC_SYMBOL(uint32_t, xkb_keysym_to_utf32, xkb_keysym_t);
FENNEC_SYMBOL(xkb_keysym_t, xkb_utf32_to_keysym, uint32_t ucs); FENNEC_SYMBOL(xkb_keysym_t, xkb_utf32_to_keysym, uint32_t);
FENNEC_SYMBOL(xkb_keysym_t, xkb_keysym_to_upper, xkb_keysym_t ks); FENNEC_SYMBOL(xkb_keysym_t, xkb_keysym_to_upper, xkb_keysym_t);
FENNEC_SYMBOL(xkb_keysym_t, xkb_keysym_to_lower, xkb_keysym_t ks); FENNEC_SYMBOL(xkb_keysym_t, xkb_keysym_to_lower, xkb_keysym_t);
FENNEC_SYMBOL(struct xkb_context*, xkb_context_new, enum xkb_context_flags flags);
FENNEC_SYMBOL(struct xkb_context*, xkb_context_ref, struct xkb_context *context); FENNEC_SYMBOL(struct xkb_context*, xkb_context_new, enum xkb_context_flags);
FENNEC_SYMBOL(void, xkb_context_unref, struct xkb_context *context); FENNEC_SYMBOL(struct xkb_context*, xkb_context_ref, struct xkb_context*);
FENNEC_SYMBOL(void, xkb_context_set_user_data, struct xkb_context *context, void *user_data); FENNEC_SYMBOL(void, xkb_context_unref, struct xkb_context*);
FENNEC_SYMBOL(void*, xkb_context_get_user_data, struct xkb_context *context); FENNEC_SYMBOL(void, xkb_context_set_user_data, struct xkb_context*, void*);
FENNEC_SYMBOL(int, xkb_context_include_path_append, struct xkb_context *context, const char *path); FENNEC_SYMBOL(void*, xkb_context_get_user_data, struct xkb_context*);
FENNEC_SYMBOL(int, xkb_context_include_path_append_default, struct xkb_context *context); FENNEC_SYMBOL(int, xkb_context_include_path_append, struct xkb_context*, const char*);
FENNEC_SYMBOL(int, xkb_context_include_path_reset_defaults, struct xkb_context *context); FENNEC_SYMBOL(int, xkb_context_include_path_append_default, struct xkb_context*);
FENNEC_SYMBOL(void, xkb_context_include_path_clear, struct xkb_context *context); FENNEC_SYMBOL(int, xkb_context_include_path_reset_defaults, struct xkb_context*);
FENNEC_SYMBOL(unsigned int, xkb_context_num_include_paths, struct xkb_context *context); FENNEC_SYMBOL(void, xkb_context_include_path_clear, struct xkb_context*);
FENNEC_SYMBOL(const char*, xkb_context_include_path_get, struct xkb_context *context, unsigned int index); FENNEC_SYMBOL(unsigned int, xkb_context_num_include_paths, struct xkb_context*);
FENNEC_SYMBOL(void, xkb_context_set_log_level, struct xkb_context *context, enum xkb_log_level level); FENNEC_SYMBOL(const char*, xkb_context_include_path_get, struct xkb_context*, unsigned int);
FENNEC_SYMBOL(enum xkb_log_level, xkb_context_get_log_level, struct xkb_context *context); FENNEC_SYMBOL(void, xkb_context_set_log_level, struct xkb_context*, enum xkb_log_level);
FENNEC_SYMBOL(void, xkb_context_set_log_verbosity, struct xkb_context *context, int verbosity); FENNEC_SYMBOL(enum xkb_log_level, xkb_context_get_log_level, struct xkb_context*);
FENNEC_SYMBOL(int, xkb_context_get_log_verbosity, struct xkb_context *context); FENNEC_SYMBOL(void, xkb_context_set_log_verbosity, struct xkb_context*, int);
FENNEC_SYMBOL(void, xkb_context_set_log_fn, struct xkb_context *context, void (*log_fn)(struct xkb_context *context, enum xkb_log_level level, const char *format, va_list args)); FENNEC_SYMBOL(int, xkb_context_get_log_verbosity, struct xkb_context*);
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_new_from_names, struct xkb_context *context, const struct xkb_rule_names *names, enum xkb_keymap_compile_flags flags); 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_file, struct xkb_context *context, FILE *file, enum xkb_keymap_format format, enum xkb_keymap_compile_flags flags);
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_new_from_string, struct xkb_context *context, const char *string, enum xkb_keymap_format format, enum xkb_keymap_compile_flags flags); 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_buffer, struct xkb_context *context, const char *buffer, size_t length, enum xkb_keymap_format format, enum xkb_keymap_compile_flags 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_ref, struct xkb_keymap *keymap); 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(void, xkb_keymap_unref, struct xkb_keymap *keymap); 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(char*, xkb_keymap_get_as_string, struct xkb_keymap *keymap, enum xkb_keymap_format format); FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_ref, struct xkb_keymap*);
FENNEC_SYMBOL(xkb_keycode_t, xkb_keymap_min_keycode, struct xkb_keymap *keymap); FENNEC_SYMBOL(void, xkb_keymap_unref, struct xkb_keymap*);
FENNEC_SYMBOL(xkb_keycode_t, xkb_keymap_max_keycode, struct xkb_keymap *keymap); FENNEC_SYMBOL(char*, xkb_keymap_get_as_string, struct xkb_keymap*, enum xkb_keymap_format);
FENNEC_SYMBOL(void, xkb_keymap_key_for_each, struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter, void *data); FENNEC_SYMBOL(xkb_keycode_t, xkb_keymap_min_keycode, struct xkb_keymap*);
FENNEC_SYMBOL(const char*, xkb_keymap_key_get_name, struct xkb_keymap *keymap, xkb_keycode_t key); FENNEC_SYMBOL(xkb_keycode_t, xkb_keymap_max_keycode, struct xkb_keymap*);
FENNEC_SYMBOL(xkb_keycode_t, xkb_keymap_key_by_name, struct xkb_keymap *keymap, const char *name); FENNEC_SYMBOL(void, xkb_keymap_key_for_each, struct xkb_keymap*, xkb_keymap_key_iter_t, void*);
FENNEC_SYMBOL(xkb_mod_index_t, xkb_keymap_num_mods, struct xkb_keymap *keymap); FENNEC_SYMBOL(const char*, xkb_keymap_key_get_name, struct xkb_keymap*, xkb_keycode_t);
FENNEC_SYMBOL(const char*, xkb_keymap_mod_get_name, struct xkb_keymap *keymap, xkb_mod_index_t idx); FENNEC_SYMBOL(xkb_keycode_t, xkb_keymap_key_by_name, struct xkb_keymap*, const char*);
FENNEC_SYMBOL(xkb_mod_index_t, xkb_keymap_mod_get_index, struct xkb_keymap *keymap, const char *name); FENNEC_SYMBOL(xkb_mod_index_t, xkb_keymap_num_mods, struct xkb_keymap*);
FENNEC_SYMBOL(xkb_layout_index_t, xkb_keymap_num_layouts, struct xkb_keymap *keymap); FENNEC_SYMBOL(const char*, xkb_keymap_mod_get_name, struct xkb_keymap*, xkb_mod_index_t);
FENNEC_SYMBOL(const char*, xkb_keymap_layout_get_name, struct xkb_keymap *keymap, xkb_layout_index_t idx); FENNEC_SYMBOL(xkb_mod_index_t, xkb_keymap_mod_get_index, struct xkb_keymap*, const char*);
FENNEC_SYMBOL(xkb_layout_index_t, xkb_keymap_layout_get_index, struct xkb_keymap *keymap, const char *name); FENNEC_SYMBOL(xkb_layout_index_t, xkb_keymap_num_layouts, struct xkb_keymap*);
FENNEC_SYMBOL(xkb_led_index_t, xkb_keymap_num_leds, struct xkb_keymap *keymap); FENNEC_SYMBOL(const char*, xkb_keymap_layout_get_name, struct xkb_keymap*, xkb_layout_index_t);
FENNEC_SYMBOL(const char*, xkb_keymap_led_get_name, struct xkb_keymap *keymap, xkb_led_index_t idx); FENNEC_SYMBOL(xkb_layout_index_t, xkb_keymap_layout_get_index, struct xkb_keymap*, const char*);
FENNEC_SYMBOL(xkb_led_index_t, xkb_keymap_led_get_index, struct xkb_keymap *keymap, const char *name); FENNEC_SYMBOL(xkb_led_index_t, xkb_keymap_num_leds, struct xkb_keymap*);
FENNEC_SYMBOL(xkb_layout_index_t, xkb_keymap_num_layouts_for_key, struct xkb_keymap *keymap, xkb_keycode_t key); FENNEC_SYMBOL(const char*, xkb_keymap_led_get_name, struct xkb_keymap*, xkb_led_index_t);
FENNEC_SYMBOL(xkb_level_index_t, xkb_keymap_num_levels_for_key, struct xkb_keymap *keymap, xkb_keycode_t key, xkb_layout_index_t layout); FENNEC_SYMBOL(xkb_led_index_t, xkb_keymap_led_get_index, struct xkb_keymap*, const char*);
FENNEC_SYMBOL(size_t, xkb_keymap_key_get_mods_for_level, struct xkb_keymap *keymap, xkb_keycode_t key, xkb_layout_index_t layout, xkb_level_index_t level, xkb_mod_mask_t *masks_out, size_t masks_size); FENNEC_SYMBOL(xkb_layout_index_t, xkb_keymap_num_layouts_for_key, struct xkb_keymap*, xkb_keycode_t);
FENNEC_SYMBOL(int, xkb_keymap_key_get_syms_by_level, struct xkb_keymap *keymap, xkb_keycode_t key, xkb_layout_index_t layout, xkb_level_index_t level, const xkb_keysym_t **syms_out); FENNEC_SYMBOL(xkb_level_index_t, xkb_keymap_num_levels_for_key, struct xkb_keymap*, xkb_keycode_t, xkb_layout_index_t);
FENNEC_SYMBOL(int, xkb_keymap_key_repeats, struct xkb_keymap *keymap, xkb_keycode_t key); 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(struct xkb_state*, xkb_state_new, struct xkb_keymap *keymap); 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(struct xkb_state*, xkb_state_ref, struct xkb_state *state); FENNEC_SYMBOL(int, xkb_keymap_key_repeats, struct xkb_keymap*, xkb_keycode_t);
FENNEC_SYMBOL(void, xkb_state_unref, struct xkb_state *state);
FENNEC_SYMBOL(struct xkb_keymap*, xkb_state_get_keymap, struct xkb_state *state); FENNEC_SYMBOL(struct xkb_state*, xkb_state_new, struct xkb_keymap*);
FENNEC_SYMBOL(enum xkb_state_component, xkb_state_update_key, struct xkb_state *state, xkb_keycode_t key, enum xkb_key_direction direction); FENNEC_SYMBOL(struct xkb_state*, xkb_state_ref, struct xkb_state*);
FENNEC_SYMBOL(enum xkb_state_component, xkb_state_update_mask, struct xkb_state *state, xkb_mod_mask_t depressed_mods, xkb_mod_mask_t latched_mods, xkb_mod_mask_t locked_mods, xkb_layout_index_t depressed_layout, xkb_layout_index_t latched_layout, xkb_layout_index_t locked_layout); FENNEC_SYMBOL(void, xkb_state_unref, struct xkb_state*);
FENNEC_SYMBOL(int, xkb_state_key_get_syms, struct xkb_state *state, xkb_keycode_t key, const xkb_keysym_t **syms_out); FENNEC_SYMBOL(struct xkb_keymap*, xkb_state_get_keymap, struct xkb_state*);
FENNEC_SYMBOL(int, xkb_state_key_get_utf8, struct xkb_state *state, xkb_keycode_t key, char *buffer, size_t size); FENNEC_SYMBOL(enum xkb_state_component, xkb_state_update_key, struct xkb_state*, xkb_keycode_t, enum xkb_key_direction);
FENNEC_SYMBOL(uint32_t, xkb_state_key_get_utf32, struct xkb_state *state, xkb_keycode_t key); 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(xkb_keysym_t, xkb_state_key_get_one_sym, struct xkb_state *state, xkb_keycode_t key); FENNEC_SYMBOL(int, xkb_state_key_get_syms, struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**);
FENNEC_SYMBOL(xkb_layout_index_t, xkb_state_key_get_layout, struct xkb_state *state, xkb_keycode_t key); FENNEC_SYMBOL(int, xkb_state_key_get_utf8, struct xkb_state*, xkb_keycode_t, char*, size_t);
FENNEC_SYMBOL(xkb_level_index_t, xkb_state_key_get_level, struct xkb_state *state, xkb_keycode_t key, xkb_layout_index_t layout); FENNEC_SYMBOL(uint32_t, xkb_state_key_get_utf32, struct xkb_state*, xkb_keycode_t);
FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_serialize_mods, struct xkb_state *state, enum xkb_state_component components); 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_serialize_layout, struct xkb_state *state, enum xkb_state_component components); FENNEC_SYMBOL(xkb_layout_index_t, xkb_state_key_get_layout, struct xkb_state*, xkb_keycode_t);
FENNEC_SYMBOL(int, xkb_state_mod_name_is_active, struct xkb_state *state, const char *name, enum xkb_state_component type); FENNEC_SYMBOL(xkb_level_index_t, xkb_state_key_get_level, struct xkb_state*, xkb_keycode_t, xkb_layout_index_t);
FENNEC_SYMBOL(int, xkb_state_mod_names_are_active, struct xkb_state *state, enum xkb_state_component type, enum xkb_state_match match, ...); FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_serialize_mods, struct xkb_state*, enum xkb_state_component);
FENNEC_SYMBOL(int, xkb_state_mod_index_is_active, struct xkb_state *state, xkb_mod_index_t idx, enum xkb_state_component type); FENNEC_SYMBOL(xkb_layout_index_t, xkb_state_serialize_layout, struct xkb_state*, enum xkb_state_component);
FENNEC_SYMBOL(int, xkb_state_mod_indices_are_active, struct xkb_state *state, enum xkb_state_component type, enum xkb_state_match match, ...); FENNEC_SYMBOL(int, xkb_state_mod_name_is_active, struct xkb_state*, const char*, enum xkb_state_component);
FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_key_get_consumed_mods2, struct xkb_state *state, xkb_keycode_t key, enum xkb_consumed_mode mode); FENNEC_SYMBOL(int, xkb_state_mod_names_are_active, struct xkb_state*, enum xkb_state_component, enum xkb_state_match, ...);
FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_key_get_consumed_mods, struct xkb_state *state, xkb_keycode_t key); 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_index_is_consumed2, struct xkb_state *state, xkb_keycode_t key, xkb_mod_index_t idx, enum xkb_consumed_mode mode); FENNEC_SYMBOL(int, xkb_state_mod_indices_are_active, struct xkb_state*, enum xkb_state_component, enum xkb_state_match, ...);
FENNEC_SYMBOL(int, xkb_state_mod_index_is_consumed, struct xkb_state *state, xkb_keycode_t key, xkb_mod_index_t idx); 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_mod_mask_remove_consumed, struct xkb_state *state, xkb_keycode_t key, xkb_mod_mask_t mask); FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_key_get_consumed_mods, struct xkb_state*, xkb_keycode_t);
FENNEC_SYMBOL(int, xkb_state_layout_name_is_active, struct xkb_state *state, const char *name, enum xkb_state_component type); 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_layout_index_is_active, struct xkb_state *state, xkb_layout_index_t idx, enum xkb_state_component type); FENNEC_SYMBOL(int, xkb_state_mod_index_is_consumed, struct xkb_state*, xkb_keycode_t, xkb_mod_index_t);
FENNEC_SYMBOL(int, xkb_state_led_name_is_active, struct xkb_state *state, const char *name); 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_led_index_is_active, struct xkb_state *state, xkb_led_index_t idx); 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_LIB
#undef FENNEC_SYMBOL #undef FENNEC_SYMBOL

View File

@@ -0,0 +1,110 @@
// =====================================================================================================================
// 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

File diff suppressed because it is too large Load Diff

View File

@@ -1,45 +0,0 @@
/*
* Copyright © 2012 Intel Corporation
*
* 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>
*/
#ifndef _XKBCOMMON_NAMES_H
#define _XKBCOMMON_NAMES_H
/**
* @file
* @brief Predefined names for common modifiers and LEDs.
*/
#define XKB_MOD_NAME_SHIFT "Shift"
#define XKB_MOD_NAME_CAPS "Lock"
#define XKB_MOD_NAME_CTRL "Control"
#define XKB_MOD_NAME_ALT "Mod1"
#define XKB_MOD_NAME_NUM "Mod2"
#define XKB_MOD_NAME_LOGO "Mod4"
#define XKB_LED_NAME_CAPS "Caps Lock"
#define XKB_LED_NAME_NUM "Num Lock"
#define XKB_LED_NAME_SCROLL "Scroll Lock"
#endif

View File

@@ -1,157 +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_XKBCOMMON_H
#define FENNEC_PLATFORM_LINUX_XKB_LIB_XKBCOMMON_H
#define FENNEC_LIB(name) extern bool FENNEC_HAS_LIB_##name;
#define FENNEC_SYMBOL(ret, fn, ...) using sym_##fn = ret(*)(__VA_ARGS__); \
extern sym_##fn fn;
#define FENNEC_GLOBAL(type, name) extern type* name;
#include <fennec/platform/linux/xkb/lib/sym.h>
/*
* 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 <fennec/platform/linux/xkb/lib/xkbcommon-names.h>
#include <fennec/platform/linux/xkb/lib/xkbcommon-keysyms.h>
#define XKB_KEYCODE_INVALID (0xffffffff)
#define XKB_LAYOUT_INVALID (0xffffffff)
#define XKB_LEVEL_INVALID (0xffffffff)
#define XKB_MOD_INVALID (0xffffffff)
#define XKB_LED_INVALID (0xffffffff)
#define XKB_KEYCODE_MAX (0xffffffff - 1)
/**
* Maximum keysym value
*
* @since 1.6.0
* @sa xkb_keysym_t
* @ingroup keysyms
*/
#define XKB_KEYSYM_MAX 0x1fffffff
/**
* Test whether a value is a valid extended keycode.
* @sa xkb_keycode_t
**/
#define xkb_keycode_is_legal_ext(key) (key <= XKB_KEYCODE_MAX)
/**
* Test whether a value is a valid X11 keycode.
* @sa xkb_keycode_t
*/
#define xkb_keycode_is_legal_x11(key) (key >= 8 && key <= 255)
/**
* Names to compile a keymap with, also known as RMLVO.
*
* The names are the common configuration values by which a user picks
* a keymap.
*
* If the entire struct is NULL, then each field is taken to be NULL.
* You should prefer passing NULL instead of choosing your own defaults.
*/
struct xkb_rule_names {
/**
* The rules file to use. The rules file describes how to interpret
* the values of the model, layout, variant and options fields.
*
* If NULL or the empty string "", a default value is used.
* If the XKB_DEFAULT_RULES environment variable is set, it is used
* as the default. Otherwise the system default is used.
*/
const char *rules;
/**
* The keyboard model by which to interpret keycodes and LEDs.
*
* If NULL or the empty string "", a default value is used.
* If the XKB_DEFAULT_MODEL environment variable is set, it is used
* as the default. Otherwise the system default is used.
*/
const char *model;
/**
* A comma separated list of layouts (languages) to include in the
* keymap.
*
* If NULL or the empty string "", a default value is used.
* If the XKB_DEFAULT_LAYOUT environment variable is set, it is used
* as the default. Otherwise the system default is used.
*/
const char *layout;
/**
* A comma separated list of variants, one per layout, which may
* modify or augment the respective layout in various ways.
*
* Generally, should either be empty or have the same number of values
* as the number of layouts. You may use empty values as in "intl,,neo".
*
* If NULL or the empty string "", and a default value is also used
* for the layout, a default value is used. Otherwise no variant is
* used.
* If the XKB_DEFAULT_VARIANT environment variable is set, it is used
* as the default. Otherwise the system default is used.
*/
const char *variant;
/**
* A comma separated list of options, through which the user specifies
* non-layout related preferences, like which key combinations are used
* for switching layouts, or which key is the Compose key.
*
* If NULL, a default value is used. If the empty string "", no
* options are used.
* If the XKB_DEFAULT_OPTIONS environment variable is set, it is used
* as the default. Otherwise the system default is used.
*/
const char *options;
};
/**
* Get the keymap as a string in the format from which it was created.
* @sa xkb_keymap_get_as_string()
**/
#define XKB_KEYMAP_USE_ORIGINAL_FORMAT ((enum xkb_keymap_format) -1)
#endif // FENNEC_PLATFORM_LINUX_XKB_LIB_XKBCOMMON_H

View File

@@ -21,6 +21,7 @@
#include <EGL/egl.h> #include <EGL/egl.h>
#include <fennec/platform/interface/gfxcontext.h> #include <fennec/platform/interface/gfxcontext.h>
#include <fennec/platform/opengl/egl/fwd.h>
namespace fennec namespace fennec
{ {
@@ -34,12 +35,26 @@ public:
bool connected() override; bool connected() override;
int32_t get_version_major() override { return _eglvmajor; } int32_t get_version_major() override { return _eglvmajor; }
int32_t get_version_minor() override { return _eglvminor; } int32_t get_version_minor() override { return _eglvminor; }
int32_t get_context_version() override { return _eglctype; } int32_t get_version() override { return _eglctype; }
const cstring& get_context_name() override; const cstring& get_name() override;
bool check_extension(const cstring& ext) override; bool check_extension(const cstring& ext) override;
gfxsurface* create_surface(window* window) override;
void make_current(gfxsurface* surface) 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: private:
EGLDisplay _egldisplay; EGLDisplay _egldisplay;
EGLContext _eglcontext; EGLContext _eglcontext;

View File

@@ -16,7 +16,27 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// ===================================================================================================================== // =====================================================================================================================
#ifndef FENNEC_CONCURRENCY_ATOMIC_H ///
#define FENNEC_CONCURRENCY_ATOMIC_H /// \file fwd.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#endif // FENNEC_CONCURRENCY_ATOMIC_H #ifndef FENNEC_PLATFORM_OPENGL_EGL_FWD_H
#define FENNEC_PLATFORM_OPENGL_EGL_FWD_H
namespace fennec
{
class eglcontext;
class eglsurface;
}
#endif // FENNEC_PLATFORM_OPENGL_EGL_FWD_H

View File

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

View File

@@ -23,8 +23,8 @@ Links:
### Structures (`gfx2d`) ### Structures (`gfx2d`)
For the 2d rendering framework, Materials need to be rendered independently because we have For the 2d rendering framework, Materials need to be rendered independently because we have
no size constraints for images. This disallows us from using a meta-shader like in no size constraints for images. This disallows us from using a meta-shader like in
the 3d rendering framework. the 3d rendering framework.
```c++ ```c++
@@ -59,6 +59,6 @@ struct Object
- Adjust Buffer Size using the counts - Adjust Buffer Size using the counts
- Insert using another atomic buffer - Insert using another atomic buffer
- Translucent objects will be sorted. We can cheat by using a z-index instead of a z-coordinate. - 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, 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. with meshes and objects being grouped by material.

View File

@@ -15,16 +15,16 @@
## Introduction ## Introduction
&ensp; This system handles the rendering of 3D meshes, materials, lights, and post-processing &ensp; This system handles the rendering of 3D meshes, materials, lights, and post-processing
effects. effects.
**DirectX will never have official support.** **DirectX will never have official support.**
If you would like to make a fork, have at it, but know that I will hold a deep disdain for you. If you would like to make a fork, have at it, but know that I will hold a deep disdain for you.
The graphics pipeline will have a buffer with a list of objects and their rendering data. The graphics pipeline will have a buffer with a list of objects and their rendering data.
This will be referred to as the Object Buffer. There will be two, for both the Deferred and Forward Passes. This will be referred to as the Object Buffer. There will be two, for both the Deferred and Forward Passes.
The buffers will be optimized by scene prediction. The buffers will be optimized by scene prediction.
This involves tracking the meshes and textures directly and indirectly used by a scene. This involves tracking the meshes and textures directly and indirectly used by a scene.
A callback function in the graphics system for scene loading can do this. A callback function in the graphics system for scene loading can do this.
@@ -66,8 +66,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. 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` 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 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`. may be transformed to use a `2:1` as if it were `1:2`.
Cubemaps and 3D textures may only be `1:1`. Cubemaps and 3D textures may only be `1:1`.

View File

@@ -14,10 +14,10 @@
## Introduction ## Introduction
&ensp; This system will handle newtonian physics for 3D rigid and soft-bodies. This should include &ensp; This system will handle newtonian physics for 3D rigid and soft-bodies. This should include
articulated skeletal systems, particle physics, and soft-body physics. The following soft-body systems articulated skeletal systems, particle physics, and soft-body physics. The following soft-body systems
will be supported with the associated implementation; elastics with finite element simulation, cloth will be supported with the associated implementation; elastics with finite element simulation, cloth
physics with position-based dynamics, oceans with iWave, 3D fluid dynamics with smoothed-particle physics with position-based dynamics, oceans with iWave, 3D fluid dynamics with smoothed-particle
hydrodynamics, 2D surface fluid dynamics with force-based dynamics. hydrodynamics, 2D surface fluid dynamics with force-based dynamics.

View File

@@ -8,10 +8,10 @@
## Introduction ## Introduction
&ensp; This system implements pathing and decision systems for general-purpose traditional &ensp; This system implements pathing and decision systems for general-purpose traditional
artifical intelligence algorithms. This library will not support Machine-Learning Artificial artifical intelligence algorithms. This library will not support Machine-Learning Artificial
Intelligence (ML/AI). This artificial intelligence method only differs in static generation Intelligence (ML/AI). This artificial intelligence method only differs in static generation
between 2D and 3D. The solvers are dimension independent since they work on a graph. between 2D and 3D. The solvers are dimension independent since they work on a graph.
## General Process ## General Process
@@ -25,5 +25,5 @@ between 2D and 3D. The solvers are dimension independent since they work on a gr
* update paths using dijkstra's algorithm * update paths using dijkstra's algorithm
* apply rigid-body forces with constraints * apply rigid-body forces with constraints
The update loop for artificial intelligence should only update every `n` ticks. Where The update loop for artificial intelligence should only update every `n` ticks. Where
`n <= k`, with `k` being the tick rate of the physics engine. `n <= k`, with `k` being the tick rate of the physics engine.

View File

@@ -16,8 +16,8 @@
## Introduction ## Introduction
&ensp; This library contains headers and classes that implement common data &ensp; This library contains headers and classes that implement common data
structures. The contents include the Containers Library of the C++ Standard structures. The contents include the Containers Library of the C++ Standard
Library and Template Library. Library and Template Library.
@@ -29,29 +29,29 @@ Library and Template Library.
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |
|:-------------------------------------|:-----------:|:------:| |:-------------------------------------|:-----------:|:------:|
| map (`std::unordered_map`) | ✅ | ✅ | | map (`std::unordered_map`) | ✅ | ✅ |
| map_sequence (`std::map`) | ⛔ | ⛔ | | map_sequence (`std::map`) | ⛔ | ⛔ |
| multiset (`std::unordered_multiset`) | ⛔ | ⛔ | | multiset (`std::unordered_multiset`) | ⛔ | ⛔ |
| multisequence (`std::multiset`) | ⛔ | ⛔ | | multisequence (`std::multiset`) | ⛔ | ⛔ |
| multimap (`std::unordered_multimap`) | ⛔ | ⛔ | | multimap (`std::unordered_multimap`) | ⛔ | ⛔ |
| multimap_sequence (`std::multimap`) | ⛔ | ⛔ | | multimap_sequence (`std::multimap`) | ⛔ | ⛔ |
| pair | ✅ | ✅ | | pair | ✅ | ✅ |
| tuple | 🚧 | 🚧 | | tuple | 🚧 | 🚧 |
| optional | ✅ | ✅ | | optional | ✅ | ✅ |
| variant | ⛔ | ⛔ | | variant | ⛔ | ⛔ |
| any | ⛔ | ⛔ | | any | ⛔ | ⛔ |
| bitset | ⛔ | ⛔ | | bitset | ⛔ | ⛔ |
| array | ✅ | ✅ | | array | ✅ | ✅ |
| dynarray (`std::vector`) | 🚧 | 🚧 | | dynarray (`std::vector`) | 🚧 | 🚧 |
| deque | ⛔ | ⛔ | | deque | ⛔ | ⛔ |
| list | ✅ | ✅ | | list | ✅ | ✅ |
| set (`std::unordered_set`) | ✅ | ✅ | | set (`std::unordered_set`) | ✅ | ✅ |
| sequence (`std::set`) | ⛔ | ⛔ | | sequence (`std::set`) | ⛔ | ⛔ |
### fennec ### fennec
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |
|:------------|:-----------:|:------:| |:------------|:-----------:|:------:|
| graph | 🚧 | 🚧 | | graph | 🚧 | 🚧 |
| object_pool | 🚧 | 🚧 | | object_pool | 🚧 | 🚧 |
| rd_tree | ✅ | ✅ | | rd_tree | ✅ | ✅ |

View File

@@ -15,41 +15,49 @@
## Introduction ## Introduction
&ensp; These files serve as general planning documentation for engine structure, systems, &ensp; These files serve as general planning documentation for engine structure, systems,
pipelines, and implementation. pipelines, and implementation.
&ensp; Implementations of core engine systems should strive to be `O(1)` in &ensp; Implementations of core engine systems should strive to be `O(1)` in
implementations, both in terms of runtime and memory performance. This is obviously implementations, both in terms of runtime and memory performance. This is obviously
not a realistic goal, so rather than the goal requiring the entire engine to be `O(1)`, not a realistic goal, so rather than the goal requiring the entire engine to be `O(1)`,
we should more specifically look at achieving `O(1)` performance on hot paths. we should more specifically look at achieving `O(1)` performance on hot paths.
I distinctly use 'strive' and 'goal' as different concepts, where designs should I distinctly use 'strive' and 'goal' as different concepts, where designs should
*strive* to accommodate function implementations for `O(1)`, however the specifics *strive* to accommodate function implementations for `O(1)`, however the specifics
of the implementation might not always be able to achieve that, so the end *goal* is of the implementation might not always be able to achieve that, so the end *goal* is
that hot paths should be `O(1)`. that hot paths should be `O(1)`.
&ensp; Functions should be highly verbose and any bugprone or erroneous behaviour should &ensp; Functions should be highly verbose and any bugprone or erroneous behaviour should
throw assertions. **DO NOT USE EXCEPTIONS**. throw assertions. **DO NOT USE EXCEPTIONS**.
&ensp; System implementations should be independent of architecture or platforms. i.e. &ensp; System implementations should be independent of architecture or platforms. i.e.
the code of the graphics system should not care if OpenGL or Vulkan is used and should the code of the graphics system should not care if OpenGL or Vulkan is used and should
not use any direct calls to OpenGL or Vulkan. not use any direct calls to OpenGL or Vulkan.
&ensp; The engine should not care about the types of objects loaded from a so/dll. In &ensp; The engine should not care about the types of objects loaded from a so/dll. In
fact, most of the code should be type independent. Any shared information among a fact, most of the code should be type independent. Any shared information among a
collection of objects should be held either implicitly or explicitly in the super-class. collection of objects should be held either implicitly or explicitly in the super-class.
It will be the responsibility of the linked code to initialize and cleanup the objects It will be the responsibility of the linked code to initialize and cleanup the objects
related to it. This principle should extend to the submodules of the engine. related to it. This principle should extend to the submodules of the engine.
&ensp; It is also best to avoid objects having behaviour that is not defined by the system &ensp; It is also best to avoid objects having behaviour that is not defined by the system
they are in. There are some exceptions in extensions or mods, which should be given they are in. There are some exceptions in extensions or mods, which should be given
configurability and programmability within those systems and their stages. This can configurability and programmability within those systems and their stages. This can
be achieved using events at different stages of those engines that are on-demand. be achieved using events at different stages of those engines that are on-demand.
## External Libraries
* `cpptrace`
* Walking the stack and retrieving information about the code is *very* platform
dependent, and it makes little sense spending days writing a library that will
be less effective.
## Definitions ## Definitions
&ensp; Many subpages of these documents will contain tables that use symbols to &ensp; Many subpages of these documents will contain tables that use symbols to
denote implementation and testing progress. The symbols are defined below. denote implementation and testing progress. The symbols are defined below.
| Symbol | Meaning | Notes | | Symbol | Meaning | Notes |
@@ -62,4 +70,7 @@ denote implementation and testing progress. The symbols are defined below.
## Libraries ## Libraries
- [C++ Language Library](./CPP_LANGUAGE.md#c-language-library-lang) - [C++ Language Library](./CPP_LANGUAGE.md#c-language-library-lang)
- [Platform Support Library](./PLATFORM_SUPPORT.md#platform--api-support) - [Platform Support Library](./PLATFORM_SUPPORT.md#platform-support-library-platform)
- [Memory Library](./MEMORY.md#memory-library-memory)
- [Containers Library](./CONTAINERS.md#containers-library-containers)
- [Language Processing Library](./LANGUAGE_PROCESSING.md#language-processing-library-langproc)

View File

@@ -26,8 +26,8 @@
## Introduction ## Introduction
&ensp; This library contains headers and classes related to the C++ language. The &ensp; This library contains headers and classes related to the C++ language. The
contents of this library include the Language Support, Diagnostics, and contents of this library include the Language Support, Diagnostics, and
Metaprogramming libraries of the C++ Standard Library and Template Library. Metaprogramming libraries of the C++ Standard Library and Template Library.
See: See:
@@ -59,22 +59,22 @@ See:
| is_null_pointer | ✅ | ✅ | | is_null_pointer | ✅ | ✅ |
| is_integral | ✅ | ✅ | | is_integral | ✅ | ✅ |
| is_floating_point | ✅ | ✅ | | is_floating_point | ✅ | ✅ |
| is_array | ✅ | | | is_array | ✅ | 🚧 |
| is_enum | ⛔ | ⛔ | | is_enum | ⛔ | ⛔ |
| is_union | ⛔ | ⛔ | | is_union | ⛔ | ⛔ |
| is_class | ✅ | ✅ | | is_class | ✅ | ✅ |
| is_function | ⛔ | ⛔ | | is_function | ⛔ | ⛔ |
| is_pointer | ✅ | ✅ | | is_pointer | ✅ | ✅ |
| is_lvalue_reference | ✅ | ✅ | | is_lvalue_reference | ✅ | ✅ |
| is_rvalue_reference | | | | is_rvalue_reference | | |
| is_member_object_pointer | ⛔ | ⛔ | | is_member_object_pointer | ⛔ | ⛔ |
| is_member_function_pointer | ⛔ | ⛔ | | is_member_function_pointer | ⛔ | ⛔ |
### Composite Types ### Composite Types
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |
|:------------------|:-----------:|:------:| |:------------------|:-----------:|:------:|
| is_fundamental | | | | is_fundamental | | |
| is_arithmetic | | | | is_arithmetic | | |
| is_scalar | ⛔ | ⛔ | | is_scalar | ⛔ | ⛔ |
| is_object | ⛔ | ⛔ | | is_object | ⛔ | ⛔ |
| is_compound | ⛔ | ⛔ | | is_compound | ⛔ | ⛔ |
@@ -84,9 +84,9 @@ See:
### Type Properties ### Type Properties
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |
|:----------------------------------|:-----------:|:------:| |:----------------------------------|:-----------:|:------:|
| is_const | | | | is_const | | |
| is_volatile | | | | is_volatile | | |
| is_trivially_copyable | | | | is_trivially_copyable | | |
| is_standard_layout | ⛔ | ⛔ | | is_standard_layout | ⛔ | ⛔ |
| has_unique_object_representations | ⛔ | ⛔ | | has_unique_object_representations | ⛔ | ⛔ |
| is_empty | ⛔ | ⛔ | | is_empty | ⛔ | ⛔ |
@@ -95,8 +95,8 @@ See:
| is_final | ⛔ | ⛔ | | is_final | ⛔ | ⛔ |
| is_aggregate | ⛔ | ⛔ | | is_aggregate | ⛔ | ⛔ |
| is_implicit_lifetime | ⛔ | ⛔ | | is_implicit_lifetime | ⛔ | ⛔ |
| is_signed | | | | is_signed | | |
| is_unsigned | | | | is_unsigned | | |
| is_bounded_array | ⛔ | ⛔ | | is_bounded_array | ⛔ | ⛔ |
| is_unbounded_array | ⛔ | ⛔ | | is_unbounded_array | ⛔ | ⛔ |
| is_scoped_enum | ⛔ | ⛔ | | is_scoped_enum | ⛔ | ⛔ |
@@ -104,16 +104,16 @@ See:
### Supported Operations ### Supported Operations
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |
|:------------------------------------|:-----------:|:------:| |:------------------------------------|:-----------:|:------:|
| is_constructible | | | | is_constructible | | |
| is_trivially_constructible | | | | is_trivially_constructible | | |
| is_nothrow_constructible | ⛔ | ⛔ | | is_nothrow_constructible | ⛔ | ⛔ |
| is_default_constructible | | | | is_default_constructible | | |
| is_trivially_default_constructible | ⛔ | ⛔ | | is_trivially_default_constructible | ⛔ | ⛔ |
| is_nothrow_default_constructible | ⛔ | ⛔ | | is_nothrow_default_constructible | ⛔ | ⛔ |
| is_copy_constructible | | | | is_copy_constructible | | |
| is_trivially_copy_constructible | ⛔ | ⛔ | | is_trivially_copy_constructible | ⛔ | ⛔ |
| is_nothrow_copy_constructible | ⛔ | ⛔ | | is_nothrow_copy_constructible | ⛔ | ⛔ |
| is_move_constructible | | | | is_move_constructible | | |
| is_trivially_move_constructible | ⛔ | ⛔ | | is_trivially_move_constructible | ⛔ | ⛔ |
| is_nothrow_move_constructible | ⛔ | ⛔ | | is_nothrow_move_constructible | ⛔ | ⛔ |
| is_destructible | ⛔ | ⛔ | | is_destructible | ⛔ | ⛔ |
@@ -137,10 +137,10 @@ See:
### Type Relationships ### Type Relationships
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |
|:------------------------------------|:-----------:|:------:| |:------------------------------------|:-----------:|:------:|
| is_same | | | | is_same | | |
| is_base_of | ❌ | ❌ | | is_base_of | ❌ | ❌ |
| is_virtual_base_of | ❌ | ❌ | | is_virtual_base_of | ❌ | ❌ |
| is_convertible | | | | is_convertible | | |
| is_nothrow_convertible | ❌ | ❌ | | is_nothrow_convertible | ❌ | ❌ |
| is_layout_compatible | ❌ | ❌ | | is_layout_compatible | ❌ | ❌ |
| is_pointer_interconvertible_base_of | ❌ | ❌ | | is_pointer_interconvertible_base_of | ❌ | ❌ |
@@ -152,19 +152,19 @@ See:
### Type Transformations ### Type Transformations
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |
|:---------------------|:-----------:|:------:| |:---------------------|:-----------:|:------:|
| add_const | | | | add_const | | |
| add_volatile | | | | add_volatile | | |
| add_cv | | | | add_cv | | |
| remove_const | | | | remove_const | | |
| remove_volatile | | | | remove_volatile | | |
| remove_cv | | | | remove_cv | | |
| add_lvalue_reference | | | | add_lvalue_reference | | |
| add_rvalue_reference | | | | add_rvalue_reference | | |
| remove_reference | | | | remove_reference | | |
| add_pointer | | | | add_pointer | | |
| remove_pointer | | | | remove_pointer | | |
| make_signed | | | | make_signed | | |
| make_unsigned | | | | make_unsigned | | |
| remove_extent | ❌ | ❌ | | remove_extent | ❌ | ❌ |
| remove_all_extents | ❌ | ❌ | | remove_all_extents | ❌ | ❌ |
@@ -174,17 +174,17 @@ See:
| aligned_storage | ❌ | ❌ | | aligned_storage | ❌ | ❌ |
| aligned_union | ❌ | ❌ | | aligned_union | ❌ | ❌ |
| aligned_union | ❌ | ❌ | | aligned_union | ❌ | ❌ |
| decay | 🚧 | 🚧 | | decay | 🚧 | 🚧 |
| remove_cvref | | | | remove_cvref | | |
| enable_if | | | | enable_if | | |
| conditional | | | | conditional | | |
| common_type | ❌ | ❌ | | common_type | ❌ | ❌ |
| common_reference | ❌ | ❌ | | common_reference | ❌ | ❌ |
| basic_common_reference | ❌ | ❌ | | basic_common_reference | ❌ | ❌ |
| underlying_type | ❌ | ❌ | | underlying_type | ❌ | ❌ |
| result_of | ❌ | ❌ | | result_of | ❌ | ❌ |
| invoke_result | ❌ | ❌ | | invoke_result | ❌ | ❌ |
| void_t | | | | void_t | | |
### Logical Operations ### Logical Operations
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |
@@ -196,9 +196,9 @@ See:
### Sequences ### Sequences
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |
|:-------------------------------------------------|:-----------:|:------:| |:-------------------------------------------------|:-----------:|:------:|
| const_sequence | | | | const_sequence | | |
| const_integer_sequence (`std::integer_sequence`) | | | | const_integer_sequence (`std::integer_sequence`) | | |
| make_integer_sequence | | | | make_integer_sequence | | |
| const_index_sequence (`std::index_sequence`) | | | | const_index_sequence (`std::index_sequence`) | | |
| make_index_sequence | | | | make_index_sequence | | |
| concat_sequence | | | | concat_sequence | | |

View File

@@ -24,7 +24,7 @@
## Introduction ## Introduction
&ensp; This file outlines the core engine structure and all necessary systems for &ensp; This file outlines the core engine structure and all necessary systems for
the engine to run. the engine to run.
@@ -35,70 +35,70 @@ This section outlines core systems to the engine and brief overviews.
### Events ### Events
&ensp; fennec will be largely event based, the system should be able to handle multiple &ensp; fennec will be largely event based, the system should be able to handle multiple
event types without having any type-specific code. There will be a few categories of events, event types without having any type-specific code. There will be a few categories of events,
predominantly on-demand and delayed events. On-demand events are fired immediately, which is predominantly on-demand and delayed events. On-demand events are fired immediately, which is
useful for events related to graphics and audio. Delayed events are fired at the next tick or useful for events related to graphics and audio. Delayed events are fired at the next tick or
after a certain period of time, this is useful for physics events which can't be handled after a certain period of time, this is useful for physics events which can't be handled
immediately without potentially harming the state of the physics engine. Events should be immediately without potentially harming the state of the physics engine. Events should be
optionally able to be handled with multithreading. optionally able to be handled with multithreading.
### Scene ### Scene
&ensp; The core structure of the engine and its levels will be a scene hierarchy. The hierarchy &ensp; The core structure of the engine and its levels will be a scene hierarchy. The hierarchy
will be implemented using a rooted-directed tree (rdtree, not to be confused with rbtree). will be implemented using a rooted-directed tree (rdtree, not to be confused with rbtree).
Each element in the tree will be a node with a name and some very basic flags. Component Each element in the tree will be a node with a name and some very basic flags. Component
dependent behaviour *must* be handled in systems to avoid the overhead of an object-oriented dependent behaviour *must* be handled in systems to avoid the overhead of an object-oriented
scene hierarchy. This is predominantly caused by the recursive nature of parsing an object- scene hierarchy. This is predominantly caused by the recursive nature of parsing an object-
oriented scene hierarchy where each node records its children and updates them accordingly. oriented scene hierarchy where each node records its children and updates them accordingly.
### Scripts ### Scripts
&ensp; Scripts won't be handled the same way scripts are in other engines, they will be translated &ensp; Scripts won't be handled the same way scripts are in other engines, they will be translated
as a system which will be data-oriented. This is to reduce the overhead of the object-oriented as a system which will be data-oriented. This is to reduce the overhead of the object-oriented
approach in C++ while maintaining the appearance of being object-oriented. approach in C++ while maintaining the appearance of being object-oriented.
### AI ### AI
&ensp; AI will be a fairly multi-parted system as we need to handle different use-cases. &ensp; AI will be a fairly multi-parted system as we need to handle different use-cases.
The first use case is characters that can "walk" and "jump" on surfaces. The second use-case The first use case is characters that can "walk" and "jump" on surfaces. The second use-case
is characters that "fly" in some manner. The static path generation will be the only difference is characters that "fly" in some manner. The static path generation will be the only difference
between 2D and 3D. between 2D and 3D.
### Physics ### Physics
&ensp; Physics, like other systems, will be separated into 2D and 3D specific implementations. &ensp; Physics, like other systems, will be separated into 2D and 3D specific implementations.
This system should be able to handle both Newtonian Rigid-Bodies and Soft-Bodies. The 2D This system should be able to handle both Newtonian Rigid-Bodies and Soft-Bodies. The 2D
and 3D systems should be able to co-exist but not interact. This is for such cases where one and 3D systems should be able to co-exist but not interact. This is for such cases where one
might decide to have a minigame with physics enabled in a 2D environment. might decide to have a minigame with physics enabled in a 2D environment.
### Graphics ### Graphics
&ensp; Graphics, like other systems, will be separated into 2D and 3D specific implementations. &ensp; Graphics, like other systems, will be separated into 2D and 3D specific implementations.
Graphics will exist on a separate thread that handles "frames" vs "ticks," see definitions below Graphics will exist on a separate thread that handles "frames" vs "ticks," see definitions below
for more information. From an abstract, the graphics system should be able to handle static models, for more information. From an abstract, the graphics system should be able to handle static models,
dynamic models, skeletons, materials, lights, lighting models, and post-processing effects. dynamic models, skeletons, materials, lights, lighting models, and post-processing effects.
### Audio ### Audio
&ensp; Audio may actually be implemented generically since the principles of spatial audio apply &ensp; Audio may actually be implemented generically since the principles of spatial audio apply
identically in both 2D and 3D. The only thing that may change for 2D is which axis is "up" and which identically in both 2D and 3D. The only thing that may change for 2D is which axis is "up" and which
axis is "forwards," for example side-scrollers vs top-down. However, this does not mandate specific axis is "forwards," for example side-scrollers vs top-down. However, this does not mandate specific
implementations and rather just aliases which axis is "up." The X-axis can always be "left" and "right" implementations and rather just aliases which axis is "up." The X-axis can always be "left" and "right"
while the Y axis may be interpreted as "up" or "forwards." Audio also won't be handled in the same while the Y axis may be interpreted as "up" or "forwards." Audio also won't be handled in the same
manner as other systems which have explicit ticks and frames. manner as other systems which have explicit ticks and frames.
## Core Game Loop ## Core Game Loop
&ensp; The core game loop is divided into Ticks and Frames. Ticks represent updates in the engine &ensp; The core game loop is divided into Ticks and Frames. Ticks represent updates in the engine
state while Frames represent the generation of the visual output of the engine. state while Frames represent the generation of the visual output of the engine.
### Tick ### Tick

View File

@@ -17,20 +17,20 @@
## Introduction ## Introduction
&ensp; This library contains implementations of headers and classes related to processing &ensp; This library contains implementations of headers and classes related to processing
languages. This includes; ascii/utf8/utf16 string processing, file formats, machine language, languages. This includes; ascii/utf8/utf16 string processing, file formats, machine language,
and programming languages. and programming languages.
&ensp; fennec should be able to process documentation in files, the main ways it will support &ensp; fennec should be able to process documentation in files, the main ways it will support
this is through Doxygen and LaTeX. Consider including binaries with releases. this is through Doxygen and LaTeX. Consider including binaries with releases.
## String Analysis (`langproc/strings`) ## String Analysis (`langproc/strings`)
&ensp; fennec reimplements the C++ Strings Library as a submodule of this library. This &ensp; fennec reimplements the C++ Strings Library as a submodule of this library. This
is because C++ `std::string` has a lot of overhead. I would say that `std::string` is because C++ `std::string` has a lot of overhead. I would say that `std::string`
is a Jeep, while `fennec::string` is an F2 Car, if that analogy makes any sense. i.e. is a Jeep, while `fennec::string` is an F2 Car, if that analogy makes any sense. i.e.
`std::string` offers a lot of use cases, but is slower, while an F2 Car is barebones and `std::string` offers a lot of use cases, but is slower, while an F2 Car is barebones and
highly performant on the right surface. highly performant on the right surface.
### Implementation ### Implementation
@@ -46,7 +46,7 @@ highly performant on the right surface.
## File System (`filesystem`) ## File System (`filesystem`)
&ensp; fennec *does not* reimplement the C++ I/O Library. What it does do &ensp; fennec *does not* reimplement the C++ I/O Library. What it does do
is create C++ classes that handle file streams, directory streams, and file paths. is create C++ classes that handle file streams, directory streams, and file paths.
### Implementation ### Implementation
@@ -86,7 +86,7 @@ certain specification. Here are some concepts that will need to be implemented a
### Writing ### Writing
&ensp; The writers will be responsible for writing data as a specific format. I.E. converting &ensp; The writers will be responsible for writing data as a specific format. I.E. converting
data values (e.g. floats, ints, etc.) to a readable language (e.g. ascii/utf8/utf16). data values (e.g. floats, ints, etc.) to a readable language (e.g. ascii/utf8/utf16).
- Writer - Writer
@@ -96,7 +96,7 @@ data values (e.g. floats, ints, etc.) to a readable language (e.g. ascii/utf8/ut
## Formats (`langproc/formats`) ## Formats (`langproc/formats`)
&ensp; This submodule will contain classes for processing a variety of file formats. &ensp; This submodule will contain classes for processing a variety of file formats.
### Serialization ### Serialization
@@ -166,8 +166,8 @@ data values (e.g. floats, ints, etc.) to a readable language (e.g. ascii/utf8/ut
#### 3D Model Formats #### 3D Model Formats
&ensp; unfortunately, most formats are esoteric due to copyright/trademark/etc. &ensp; unfortunately, most formats are esoteric due to copyright/trademark/etc.
I will be using assimp for the time being, below is a list of formats supported I will be using assimp for the time being, below is a list of formats supported
by assimp. by assimp.
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |

View File

@@ -14,9 +14,9 @@
## Introduction ## Introduction
&ensp; This library contains headers and classes related to memory allocation and &ensp; This library contains headers and classes related to memory allocation and
management in C++. The contents include the Memory Management Library of management in C++. The contents include the Memory Management Library of
the C++ Standard Library and Template Library. This pulls some functions from the the C++ Standard Library and Template Library. This pulls some functions from the
C stdlib and either wraps them or aliases them. C stdlib and either wraps them or aliases them.

View File

@@ -15,8 +15,8 @@
## Introduction ## Introduction
&ensp; The platform support library will include headers, functions, and classes related &ensp; The platform support library will include headers, functions, and classes related
to supporting various platforms. Platforms may be defined as any Hardware, OS, or to supporting various platforms. Platforms may be defined as any Hardware, OS, or
Drivers that must be initialized for the engine context. Drivers that must be initialized for the engine context.
@@ -48,14 +48,14 @@ Platform Support will be implemented in the following order:
- Vulkan - Vulkan
- Metal - Metal
&ensp; Linux Wayland will be implemented first. Once setup, the core engine will be &ensp; Linux Wayland will be implemented first. Once setup, the core engine will be
implemented and tested on top of Wayland. Once the engine is in a stable state, implemented and tested on top of Wayland. Once the engine is in a stable state,
then support for other platforms will be resumed. then support for other platforms will be resumed.
## Consoles ## Consoles
&ensp; Most consoles will never get official platform support due to NDAs which conflict &ensp; Most consoles will never get official platform support due to NDAs which conflict
with the principles of this engine. fennec will avoid using proprietary libraries except 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 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. with any drivers required for the listed operating systems above, even if proprietary.

View File

@@ -138,8 +138,8 @@ file& file::operator=(file&& file) noexcept {
_error = file._error; _error = file._error;
file._handle = nullptr; file._handle = nullptr;
file._path = ""; file._path = "";
file._error = nullptr; file._error = nullptr;
return *this; return *this;
} }
@@ -193,7 +193,7 @@ bool file::open(const string& p, uint8_t mode) {
} }
// Attempt to open the file // Attempt to open the file
_handle = fopen(p, fmode_translate(mode)); _handle = fopen(p.cstr(), fmode_translate(mode));
// Validate the file // Validate the file
if (_handle == nullptr) { if (_handle == nullptr) {
@@ -233,7 +233,7 @@ bool file::open(const path& p, uint8_t mode) {
} }
// Attempt to open the file // Attempt to open the file
_handle = fopen(p.str(), fmode_translate(mode)); _handle = fopen(p.cstr(), fmode_translate(mode));
// Validate the file // Validate the file
if (_handle == nullptr) { if (_handle == nullptr) {
@@ -313,7 +313,7 @@ bool file::erase() {
} }
// Erase the file // Erase the file
remove(path.str()); remove(path.cstr());
return false; return false;
} }
@@ -335,7 +335,7 @@ bool file::rename(const cstring& str) {
} }
// Attempt to open the new file // Attempt to open the new file
FILE* fnew = fopen(fpath.str(), "wx"); FILE* fnew = fopen(fpath.cstr(), "wx");
// Check for open failure // Check for open failure
if (fnew == nullptr) { if (fnew == nullptr) {
@@ -395,7 +395,7 @@ bool file::rename(const cstring& str) {
fclose(_handle); fclose(_handle);
// Reopen the new file // Reopen the new file
_handle = freopen(fpath.str(), fmode_translate(_mode), fnew); _handle = freopen(fpath.cstr(), fmode_translate(_mode), fnew);
// Check for open failure // Check for open failure
if (_handle == nullptr) { if (_handle == nullptr) {
@@ -404,7 +404,7 @@ bool file::rename(const cstring& str) {
} }
// Erase the old file // Erase the old file
remove(_path.str()); remove(_path.cstr());
// Set the new path // Set the new path
_path = fpath; _path = fpath;
@@ -429,7 +429,7 @@ bool file::rename(const string& str) {
} }
// Attempt to open the new file // Attempt to open the new file
FILE* fnew = fopen(fpath.str(), "wx"); FILE* fnew = fopen(fpath.cstr(), "wx");
// Check for open failure // Check for open failure
if (fnew == nullptr) { if (fnew == nullptr) {
@@ -488,7 +488,7 @@ bool file::rename(const string& str) {
fclose(_handle); fclose(_handle);
// Reopen the new file // Reopen the new file
_handle = freopen(_path.str(), fmode_translate(_mode), fnew); _handle = freopen(_path.cstr(), fmode_translate(_mode), fnew);
// Check for open failure // Check for open failure
if (_handle == nullptr) { if (_handle == nullptr) {
@@ -518,7 +518,7 @@ bool file::rename(const path& p) {
} }
// Attempt to open the new file // Attempt to open the new file
FILE* fnew = fopen(fpath.str(), "wx"); FILE* fnew = fopen(fpath.cstr(), "wx");
// Check for open failure // Check for open failure
if (fnew == nullptr) { if (fnew == nullptr) {
@@ -577,7 +577,7 @@ bool file::rename(const path& p) {
fclose(_handle); fclose(_handle);
// Reopen the new file // Reopen the new file
_handle = freopen(_path.str(), fmode_translate(_mode), fnew); _handle = freopen(_path.cstr(), fmode_translate(_mode), fnew);
// Check for open failure // Check for open failure
if (_handle == nullptr) { if (_handle == nullptr) {
@@ -608,7 +608,7 @@ file file::copy(const cstring& str) {
} }
// Attempt to open the new file // Attempt to open the new file
FILE* fnew = fopen(fpath.str(), "wx"); FILE* fnew = fopen(fpath.cstr(), "wx");
// Check for open failure // Check for open failure
if (fnew == nullptr) { if (fnew == nullptr) {
@@ -698,7 +698,7 @@ file file::copy(const string& str) {
} }
// Attempt to open the new file // Attempt to open the new file
FILE* fnew = fopen(fpath.str(), "wx"); FILE* fnew = fopen(fpath.cstr(), "wx");
// Check for open failure // Check for open failure
if (fnew == nullptr) { if (fnew == nullptr) {
@@ -789,7 +789,7 @@ file file::copy(const path& p) {
} }
// Attempt to open the new file // Attempt to open the new file
FILE* fnew = fopen(fpath.str(), "wx"); FILE* fnew = fopen(fpath.cstr(), "wx");
// Check for open failure // Check for open failure
if (fnew == nullptr) { if (fnew == nullptr) {
@@ -989,7 +989,7 @@ wstring file::getwline() {
// Check if there is a file // Check if there is a file
if (_handle == nullptr) { if (_handle == nullptr) {
return 0; return _wstring{ L"" };
} }
// Read the next line; // Read the next line;

View File

@@ -40,13 +40,13 @@ path path::current() {
path path::current() { path path::current() {
char cstr[PATH_MAX]; char cstr[PATH_MAX];
if (getcwd(cstr, sizeof(cstr)) == nullptr) { if (getcwd(cstr, sizeof(cstr)) == nullptr) {
return string(""); return path("");
} }
return path(cstring(cstr, strlen(cstr) + 1)); return path(cstring(cstr, strlen(cstr) + 1));
} }
path path::current(const path& path) { path path::current(const path& path) {
if (chdir(path._str)) { if (chdir(path._str.cstr())) {
return fennec::path(""); return fennec::path("");
} }
return current(); return current();

View File

@@ -29,7 +29,7 @@ static constexpr void insert_driver(list<platform::driver<CtorT>>& drvrs, CtorT
iter_t it = drvrs.begin(); iter_t it = drvrs.begin();
while (it != drvrs.end()) { while (it != drvrs.end()) {
if (priority > it->priority) { if (priority >= it->priority) {
break; break;
} }
} }

View File

@@ -18,9 +18,11 @@
#include <fennec/platform/linux/wayland/display.h> #include <fennec/platform/linux/wayland/display.h>
#include <fennec/platform/linux/wayland/lib/loader.h> #include <fennec/platform/linux/wayland/lib/loader.h>
#include <fennec/platform/linux/wayland/lib/wayland-client.h> #include <fennec/platform/linux/wayland/lib/wayland.h>
#include <fennec/lang/startup.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 namespace fennec
{ {
@@ -42,7 +44,6 @@ wayland_display::wayland_display(platform* platform)
, _handle(nullptr) , _handle(nullptr)
, _registry(nullptr) , _registry(nullptr)
, _compositor(nullptr) , _compositor(nullptr)
, _shell(nullptr)
, _seat(nullptr) , _seat(nullptr)
, _shm(nullptr) , _shm(nullptr)
, _fifo(false) { , _fifo(false) {
@@ -89,14 +90,13 @@ bool wayland_display::connected() const {
return _handle != nullptr; return _handle != nullptr;
} }
window* wayland_display::create_window() { window* wayland_display::create_window(window* parent) {
return nullptr; return new wayland_window(this, static_cast<wayland_window*>(parent));
} }
void wayland_display::cleanup() { void wayland_display::cleanup() {
// Cleanup members // Cleanup members
if (_shell) wl_shell_destroy(_shell);
if (_compositor) wl_compositor_destroy(_compositor); if (_compositor) wl_compositor_destroy(_compositor);
if (_registry) wl_registry_destroy(_registry); if (_registry) wl_registry_destroy(_registry);
if (_handle) { if (_handle) {
@@ -104,7 +104,6 @@ void wayland_display::cleanup() {
wl_display_disconnect(_handle); wl_display_disconnect(_handle);
} }
_shell = nullptr;
_compositor = nullptr; _compositor = nullptr;
_registry = nullptr; _registry = nullptr;
_handle = nullptr; _handle = nullptr;
@@ -121,11 +120,9 @@ void wayland_display::listen_global(void* data, wl_registry* registry, uint32_t
const cstring interface = cstring(itfc, strlen(itfc) + 1); const cstring interface = cstring(itfc, strlen(itfc) + 1);
if (interface == "wl_compositor") { if (interface == "wl_compositor") {
device->_compositor = static_cast<wl_compositor*>(wl_registry_bind(registry, name, wl_compositor_interface, version)); device->_compositor = static_cast<wl_compositor*>(wl_registry_bind(registry, name, &wl_compositor_interface, version));
} else if (interface == "wl_shell") {
device->_shell = static_cast<wl_shell*>(wl_registry_bind(registry, name, wl_shell_interface, version));
} else if (interface == "wl_seat") { } else if (interface == "wl_seat") {
device->_seat = static_cast<wl_seat*>(wl_registry_bind(registry, name, wl_seat_interface, version)); device->_seat = static_cast<wl_seat*>(wl_registry_bind(registry, name, &wl_seat_interface, version));
wl_seat_add_listener(device->_seat, &seat_listener, device); wl_seat_add_listener(device->_seat, &seat_listener, device);
} else if (interface == "wp_fifo_manager_v1") { } else if (interface == "wp_fifo_manager_v1") {
device->_fifo = true; device->_fifo = true;

View File

@@ -16,13 +16,13 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// ===================================================================================================================== // =====================================================================================================================
#include <fennec/platform/linux/wayland/lib/wayland-client.h> #include <fennec/platform/linux/wayland/lib/headers/wayland-client-protocols.h>
#include <fennec/platform/linux/wayland/lib/loader.h> #include <fennec/platform/linux/wayland/lib/loader.h>
#define FENNEC_LIB(name) bool FENNEC_HAS_LIB_##name; #define FENNEC_LIB(name) bool FENNEC_HAS_LIB_##name;
#define FENNEC_SYMBOL(ret, fn, ...) using sym_##fn = ret(*)(__VA_ARGS__); \ #define FENNEC_SYMBOL(ret, fn, ...) using WAYLAND_sym_##fn = ret(*)(__VA_ARGS__); \
sym_##fn fn; WAYLAND_sym_##fn WAYLAND_##fn;
#define FENNEC_GLOBAL(type, name) type* name; #define FENNEC_GLOBAL(type, name) type* WAYLAND_##name;
#include <fennec/platform/linux/wayland/lib/sym.h> #include <fennec/platform/linux/wayland/lib/sym.h>
namespace fennec namespace fennec
@@ -57,10 +57,10 @@ bool load_symbols(platform* platform) {
return false; \ return false; \
} \ } \
current_lib = &_FENNEC_LIB_##lib; current_lib = &_FENNEC_LIB_##lib;
#define FENNEC_SYMBOL(ret, fn, ...) fn = (sym_##fn)(platform->find_symbol(current_lib->obj, #fn)); \ #define FENNEC_SYMBOL(ret, fn, ...) WAYLAND_##fn = (WAYLAND_sym_##fn)(platform->find_symbol(current_lib->obj, #fn)); \
assertf(fn != nullptr, "Failed to find symbol: " #fn); assertf(WAYLAND_##fn != nullptr, "Failed to find symbol: " #fn);
#define FENNEC_GLOBAL(type, name) name = (type*)(platform->find_symbol(current_lib->obj, #name)); \ #define FENNEC_GLOBAL(type, name) WAYLAND_##name = (type*)(platform->find_symbol(current_lib->obj, #name)); \
assertf(name != nullptr, "Failed to find global: " #name); assertf(WAYLAND_##name != nullptr, "Failed to find global: " #name);
#include <fennec/platform/linux/wayland/lib/sym.h> #include <fennec/platform/linux/wayland/lib/sym.h>
@@ -74,9 +74,9 @@ void unload_symbols(platform* platform) {
} }
#define FENNEC_LIB(lib) platform->unload_object(_FENNEC_LIB_##lib.obj); \ #define FENNEC_LIB(lib) platform->unload_object(_FENNEC_LIB_##lib.obj); \
_FENNEC_LIB_##lib.obj = nullptr; _FENNEC_LIB_##lib.obj = nullptr;
#define FENNEC_SYMBOL(ret, fn, ...) fn = nullptr; #define FENNEC_SYMBOL(ret, fn, ...) WAYLAND_##fn = nullptr;
#define FENNEC_GLOBAL(type, name) name = nullptr; #define FENNEC_GLOBAL(type, name) WAYLAND_##name = nullptr;
#include <fennec/platform/linux/wayland/lib/sym.h> #include <fennec/platform/linux/wayland/lib/sym.h>
} }

View File

@@ -0,0 +1,139 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/platform/interface/gfxcontext.h>
#include <fennec/platform/interface/gfxsurface.h>
#include <fennec/platform/linux/wayland/window.h>
#include <fennec/platform/linux/wayland/lib/wayland.h>
namespace fennec
{
bool wayland_window::running() {
return _surface != nullptr;
}
void wayland_window::configure(const config& config) {
_config = config;
}
bool wayland_window::initialize(bool) {
wayland_display* display = static_cast<wayland_display*>(_display);
_handle = wl_compositor_create_surface(display->get_compositor());
_surface = display->get_context()->create_surface(this);
return false;
}
bool wayland_window::shutdown() {
delete _surface;
wl_surface_destroy(_handle);
_display = nullptr;
_surface = nullptr;
_shell = nullptr;
_handle = nullptr;
return false;
}
bool wayland_window::set_title(const cstring& title) {
if (not _config) {
return true;
}
_config->title = title;
wl_shell_surface_set_title(_shell, _config->title.cstr());
return false;
}
bool wayland_window::set_title(const string& title) {
if (not _config) {
return true;
}
_config->title = title;
wl_shell_surface_set_title(_shell, _config->title.cstr());
return false;
}
bool wayland_window::set_width(size_t w) {
if (not _config) {
return true;
}
_config->width = w;
_surface->resize(_config->width, _config->height);
return false;
}
bool wayland_window::set_height(size_t h) {
if (not _config) {
return true;
}
_config->height = h;
_surface->resize(_config->width, _config->height);
return false;
}
bool wayland_window::resize(size_t w, size_t h) {
if (not _config) {
return true;
}
_config->width = w;
_config->height = h;
_surface->resize(_config->width, _config->height);
return false;
}
bool wayland_window::set_resizable(bool) {
return false; // TODO
}
bool wayland_window::set_fullscreen_mode(fullscreen_mode) {
return false; // TODO
}
bool wayland_window::grab_keyboard(bool) {
return false; // TODO
}
bool wayland_window::grab_mouse(bool) {
return false; // TODO
}
bool wayland_window::block_screensaver(bool) {
return false; // TODO
}
wayland_window::wayland_window(wayland_display* display, wayland_window* parent)
: window(display, parent, this)
, _handle()
, _shell()
, _nfs_width(0), _nfs_height(0) {
}
wayland_window::~wayland_window() {
wayland_window::shutdown();
}
}

View File

@@ -16,16 +16,16 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// ===================================================================================================================== // =====================================================================================================================
#define FENNEC_LIB(name) bool FENNEC_HAS_LIB_##name; #include <fennec/platform/linux/xkb/lib/xkb.h>
#define FENNEC_SYMBOL(ret, fn, ...) using sym_##fn = ret(*)(__VA_ARGS__); \
sym_##fn fn;
#define FENNEC_GLOBAL(type, name) type* name;
#include <fennec/platform/linux/xkb/lib/sym.h>
#include <fennec/platform/linux/xkb/lib/xkbcommon.h>
#include <fennec/platform/linux/xkb/lib/loader.h> #include <fennec/platform/linux/xkb/lib/loader.h>
#include <fennec/platform/interface/platform.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 fennec
{ {
@@ -58,10 +58,10 @@ bool load_symbols(platform* platform) {
return false; \ return false; \
} \ } \
current_lib = &_FENNEC_LIB_##lib; current_lib = &_FENNEC_LIB_##lib;
#define FENNEC_SYMBOL(ret, fn, ...) fn = (sym_##fn)(platform->find_symbol(current_lib->obj, #fn)); \ #define FENNEC_SYMBOL(ret, fn, ...) XKB_##fn = (XKB_sym_##fn)(platform->find_symbol(current_lib->obj, #fn)); \
assertf(fn != nullptr, "Failed to find symbol: " #fn); assertf(XKB_##fn != nullptr, "Failed to find symbol: " #fn);
#define FENNEC_GLOBAL(type, name) name = (type*)(platform->find_symbol(current_lib->obj, #name)); \ #define FENNEC_GLOBAL(type, name) XKB_##name = (type*)(platform->find_symbol(current_lib->obj, #name)); \
assertf(name != nullptr, "Failed to find global: " #name); assertf(XKB_##name != nullptr, "Failed to find global: " #name);
#include <fennec/platform/linux/xkb/lib/sym.h> #include <fennec/platform/linux/xkb/lib/sym.h>
@@ -76,8 +76,8 @@ void unload_symbols(platform* platform) {
#define FENNEC_LIB(lib) platform->unload_object(_FENNEC_LIB_##lib.obj); \ #define FENNEC_LIB(lib) platform->unload_object(_FENNEC_LIB_##lib.obj); \
_FENNEC_LIB_##lib.obj = nullptr; _FENNEC_LIB_##lib.obj = nullptr;
#define FENNEC_SYMBOL(ret, fn, ...) fn = nullptr; #define FENNEC_SYMBOL(ret, fn, ...) XKB_##fn = nullptr;
#define FENNEC_GLOBAL(type, name) name = nullptr; #define FENNEC_GLOBAL(type, name) XKB_##name = nullptr;
#include <fennec/platform/linux/xkb/lib/sym.h> #include <fennec/platform/linux/xkb/lib/sym.h>
} }

View File

@@ -21,6 +21,7 @@
#include <fennec/platform/interface/display.h> #include <fennec/platform/interface/display.h>
#include <fennec/platform/interface/platform.h> #include <fennec/platform/interface/platform.h>
#include <fennec/platform/opengl/egl/context.h> #include <fennec/platform/opengl/egl/context.h>
#include <fennec/platform/opengl/egl/surface.h>
#include <GL/gl.h> #include <GL/gl.h>
@@ -40,7 +41,10 @@ STATIC_CONSTRUCTOR(_egl_init) {
} }
eglcontext::eglcontext(display* display) eglcontext::eglcontext(display* display)
: gfxcontext(display, "EGL", this) { : gfxcontext(display, "EGL", this)
, _egldisplay(nullptr), _eglcontext(nullptr)
, _eglconfig(), _eglvmajor(0), _eglvminor(0)
, _eglctype(0), _extensions(nullptr) {
// Get the display format // Get the display format
const display::pixel_format& fmt = _display->get_color_format(); const display::pixel_format& fmt = _display->get_color_format();
@@ -121,7 +125,7 @@ bool eglcontext::connected() {
return _eglcontext != nullptr; return _eglcontext != nullptr;
} }
const cstring& eglcontext::get_context_name() { const cstring& eglcontext::get_name() {
static constexpr cstring opengl = "OpenGL"; static constexpr cstring opengl = "OpenGL";
static constexpr cstring gles = "GLES"; static constexpr cstring gles = "GLES";
static constexpr cstring openvg = "OpenVG"; // this should never be used static constexpr cstring openvg = "OpenVG"; // this should never be used
@@ -137,8 +141,13 @@ bool eglcontext::check_extension(const cstring& ext) {
return _extensions.find(ext) != _extensions.size(); return _extensions.find(ext) != _extensions.size();
} }
void eglcontext::make_current(gfxsurface*) { 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() { void eglcontext::cleanup() {

View File

@@ -0,0 +1,66 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/platform/opengl/egl/surface.h>
#include <fennec/platform/linux/wayland/lib/wayland.h>
namespace fennec
{
eglsurface::~eglsurface() {
if (_window->is_type<wayland_window>()) {
wl_egl_window_destroy(static_cast<wl_egl_window*>(_handle));
}
}
void eglsurface::resize(size_t width, size_t height) {
gfxsurface::resize(width, height);
if (_window->is_type<wayland_window>()) {
wl_egl_window_resize(static_cast<wl_egl_window*>(_handle), width, height, 0, 0);
}
}
eglsurface::eglsurface(eglcontext* context, window* window)
: gfxsurface(context, window, this)
, _handle(nullptr)
, _surface(nullptr) {
const window::config& config = window->get_config();
if (window->is_type<wayland_window>()) {
_handle = wl_egl_window_create(window->get_native_handle(), config.width, config.height);
}
assert(
_handle != nullptr,
"Failed to create egl window!"
);
eglCreateWindowSurface(
context->get_egl_display(),
context->get_egl_config(),
reinterpret_cast<EGLNativeWindowType>(_handle),
nullptr
);
assert(
EGL_TRUE == eglMakeCurrent(context->get_egl_display(), _surface, _surface, context->get_egl_context()),
"Failed to create egl window!"
);
}
}

View File

@@ -38,10 +38,10 @@ void unix_platform::unload_object(shared_object* obj) {
platform::symbol unix_platform::find_symbol(shared_object* obj, const cstring& name) { platform::symbol unix_platform::find_symbol(shared_object* obj, const cstring& name) {
string _name = name; string _name = name;
void* symbol = dlsym(obj, _name); void* symbol = dlsym(obj, _name.cstr());
if (symbol == nullptr) { if (symbol == nullptr) {
_name = '_' + _name; _name = '_' + _name;
symbol = dlsym(obj, _name); symbol = dlsym(obj, _name.cstr());
} }
return symbol; return symbol;
} }

View File

@@ -16,8 +16,6 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// ===================================================================================================================== // =====================================================================================================================
#include <iostream>
#include "tests/test_lang.h" #include "tests/test_lang.h"
#include "tests/test_math.h" #include "tests/test_math.h"
#include "tests/test_memory.h" #include "tests/test_memory.h"
@@ -27,7 +25,6 @@
#include "tests/test_langproc.h" #include "tests/test_langproc.h"
#include "tests/test_platform.h" #include "tests/test_platform.h"
int main(int, char **) int main(int, char **)
{ {
srand(0); srand(0);

View File

@@ -60,12 +60,12 @@ inline std::ostream& operator<<(std::ostream& os, const quaternion<ScalarT>& q)
// Helper for printing strings // Helper for printing strings
inline std::ostream& operator<<(std::ostream& os, const cstring& str) { inline std::ostream& operator<<(std::ostream& os, const cstring& str) {
return os << *str; return os << str.data();
} }
// Helper for printing strings // Helper for printing strings
inline std::ostream& operator<<(std::ostream& os, const string& str) { inline std::ostream& operator<<(std::ostream& os, const string& str) {
return os << *str; return os << str.cstr();
} }
// Helper for printing strings // Helper for printing strings

View File

@@ -55,6 +55,11 @@ inline void fennec_test_containers_rdtree() {
fennec_test_spacer(1); fennec_test_spacer(1);
test.traverse<tree_t::pre_order>([](size_t i, size_t n) -> uint8_t {
assertf(i + 1 == n, "Tree Traverse Test Failed");
return traversal_control_continue;
});
test.erase(0); test.erase(0);
fennec_test_run(test.empty(), true); fennec_test_run(test.empty(), true);

View File

@@ -34,13 +34,33 @@ inline void fennec_test_platform() {
platform* instance = platform::instance(); platform* instance = platform::instance();
instance->initialize(); instance->initialize();
fennec_test_run(instance->get_display() != nullptr, true); display* display = instance->get_display();
fennec_test_run(instance->get_display()->get_context() != nullptr, true);
std::cout << instance->get_display()->get_context()->get_context_name() << " "; fennec_test_run(display != nullptr, true);
std::cout << instance->get_display()->get_context()->get_version_major() << "."; fennec_test_run(display->get_context() != nullptr, true);
std::cout << instance->get_display()->get_context()->get_version_minor() << std::endl;
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(); instance->shutdown();
} }