From 7493b5252a4a97ca852a90c236ce857f494c36ec Mon Sep 17 00:00:00 2001 From: Medusa Slockbower Date: Sat, 26 Jul 2025 20:57:25 -0400 Subject: [PATCH] - More implementations and dependencies for Linux Wayland support --- CMakeLists.txt | 28 +- PLANNING.md | 1 - cmake/build.cmake | 2 + cmake/compiler.cmake | 2 + cmake/default_user.cmake | 35 + cmake/gcc.cmake | 4 +- cmake/linux.cmake | 10 +- cmake/opengl.cmake | 48 + cmake/platform.cmake | 11 +- cmake/unix.cmake | 2 + cmake/version.cmake | 33 + cmake/wayland.cmake | 51 +- doxy/Doxyfile | 2 +- include/fennec/concurrency/atomic.h | 22 + include/fennec/concurrency/mutex.h | 22 + include/fennec/concurrency/thread.h | 22 + include/fennec/containers/array.h | 10 +- include/fennec/containers/dynarray.h | 70 +- include/fennec/containers/list.h | 102 +- include/fennec/containers/map.h | 12 +- include/fennec/containers/optional.h | 18 +- include/fennec/containers/set.h | 14 +- include/fennec/core/engine.h | 5 +- include/fennec/core/event.h | 61 + include/fennec/fproc/filesystem/path.h | 6 +- include/fennec/fproc/strings/cstring.h | 26 +- include/fennec/fproc/strings/string.h | 16 +- include/fennec/fproc/strings/wcstring.h | 15 + include/fennec/fproc/strings/wstring.h | 53 +- include/fennec/lang/assert.h | 2 +- include/fennec/lang/constants.h | 4 +- include/fennec/lang/detail/__int.h | 2 +- .../sym_def.h => lang/detail/__typeuuid.h} | 22 +- include/fennec/lang/hashing.h | 6 +- include/fennec/lang/intrinsics.h | 2 +- include/fennec/lang/type_traits.h | 8 + include/fennec/lang/types.h | 16 +- include/fennec/lang/typeuuid.h | 47 + include/fennec/math/common.h | 2 +- include/fennec/math/ext/constants.h | 2 +- include/fennec/math/vector_storage.h | 4 +- include/fennec/memory/allocator.h | 29 +- include/fennec/memory/bytes.h | 4 +- include/fennec/memory/detail/__string.h | 4 +- include/fennec/memory/new.h | 3 + .../fennec/platform/interface/displaydev.h | 71 + include/fennec/platform/interface/fwd.h | 5 +- .../interface/{display.h => gfxcontext.h} | 24 +- .../fennec/platform/interface/gfxsurface.h | 48 + .../display.h => interface/inputdevice.h} | 24 +- include/fennec/platform/interface/platform.h | 12 +- include/fennec/platform/interface/window.h | 59 +- include/fennec/platform/linux/platform.h | 14 +- .../platform/linux/wayland/displaydev.h | 71 + include/fennec/platform/linux/wayland/fwd.h | 30 + .../fennec/platform/linux/wayland/lib/fwd.h | 43 +- .../fennec/platform/linux/wayland/lib/sym.h | 80 +- .../linux/wayland/lib/wayland-client.h | 2004 +++++++++++++++++ .../platform/linux/wayland/lib/wayland-util.h | 198 ++ .../fennec/platform/linux/wayland/window.h | 29 +- include/fennec/platform/opengl/egl/context.h | 44 + include/fennec/platform/opengl/egl/surface.h | 43 + .../wayland/display.cpp => core/event.cpp} | 42 +- source/fproc/filesystem/file.cpp | 2 +- source/fproc/filesystem/path.cpp | 2 +- source/memory/new.cpp | 2 +- source/platform/interface/displaydev.cpp | 37 + source/platform/interface/gfxcontext.cpp | 30 + source/platform/interface/gfxsurface.cpp | 28 + source/platform/interface/platform.cpp | 3 +- source/platform/interface/window.cpp | 7 +- source/platform/linux/platform.cpp | 34 +- source/platform/linux/wayland/displaydev.cpp | 98 + source/platform/linux/wayland/lib/dyn.cpp | 14 +- source/platform/linux/wayland/window.cpp | 86 + test/tests/containers/test_dynarray.h | 1 - test/tests/platform/linux/test_wayland.h | 2 +- test/tests/platform/test_linux.h | 2 +- 78 files changed, 3733 insertions(+), 316 deletions(-) create mode 100644 cmake/default_user.cmake create mode 100644 cmake/opengl.cmake create mode 100644 cmake/version.cmake create mode 100644 include/fennec/concurrency/atomic.h create mode 100644 include/fennec/concurrency/mutex.h create mode 100644 include/fennec/concurrency/thread.h create mode 100644 include/fennec/core/event.h rename include/fennec/{platform/linux/wayland/lib/sym_def.h => lang/detail/__typeuuid.h} (70%) create mode 100644 include/fennec/lang/typeuuid.h create mode 100644 include/fennec/platform/interface/displaydev.h rename include/fennec/platform/interface/{display.h => gfxcontext.h} (77%) create mode 100644 include/fennec/platform/interface/gfxsurface.h rename include/fennec/platform/{linux/wayland/display.h => interface/inputdevice.h} (63%) create mode 100644 include/fennec/platform/linux/wayland/displaydev.h create mode 100644 include/fennec/platform/linux/wayland/fwd.h create mode 100644 include/fennec/platform/linux/wayland/lib/wayland-client.h create mode 100644 include/fennec/platform/linux/wayland/lib/wayland-util.h create mode 100644 include/fennec/platform/opengl/egl/context.h create mode 100644 include/fennec/platform/opengl/egl/surface.h rename source/{platform/linux/wayland/display.cpp => core/event.cpp} (56%) create mode 100644 source/platform/interface/displaydev.cpp create mode 100644 source/platform/interface/gfxcontext.cpp create mode 100644 source/platform/interface/gfxsurface.cpp create mode 100644 source/platform/linux/wayland/displaydev.cpp create mode 100644 source/platform/linux/wayland/window.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2887968..c31dadb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,7 @@ set(CMAKE_C_STANDARD 23) set(FENNEC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) # include scripts +include("${FENNEC_SOURCE_DIR}/cmake/version.cmake") include("${FENNEC_SOURCE_DIR}/cmake/platform.cmake") include("${FENNEC_SOURCE_DIR}/cmake/build.cmake") include("${FENNEC_SOURCE_DIR}/cmake/compiler.cmake") @@ -60,10 +61,14 @@ add_library(fennec STATIC # CONTAINERS =========================================================================================================== include/fennec/containers/array.h include/fennec/containers/dynarray.h + include/fennec/containers/list.h include/fennec/containers/map.h include/fennec/containers/optional.h include/fennec/containers/pair.h include/fennec/containers/set.h + include/fennec/containers/tuple.h + + include/fennec/containers/detail/__tuple.h # LANG ================================================================================================================= @@ -79,9 +84,11 @@ add_library(fennec STATIC include/fennec/lang/numeric_transforms.h include/fennec/lang/sequences.h include/fennec/lang/type_identity.h + include/fennec/lang/type_operators.h include/fennec/lang/type_sequences.h include/fennec/lang/type_traits.h include/fennec/lang/type_transforms.h + include/fennec/lang/typeuuid.h include/fennec/lang/types.h include/fennec/lang/utility.h include/fennec/lang/integer.h @@ -93,6 +100,7 @@ add_library(fennec STATIC include/fennec/lang/detail/__type_traits.h include/fennec/lang/detail/__type_transforms.h include/fennec/lang/detail/__type_sequences.h + include/fennec/lang/detail/__typeuuid.h include/fennec/lang/assert.h source/lang/assert.cpp @@ -165,17 +173,19 @@ add_library(fennec STATIC include/fennec/platform/interface/fwd.h include/fennec/platform/interface/dialog.h - include/fennec/platform/interface/display.h - include/fennec/platform/interface/window.h source/platform/interface/window.cpp - include/fennec/platform/interface/platform.h source/platform/interface/platform.cpp - + include/fennec/platform/interface/displaydev.h source/platform/interface/displaydev.cpp + include/fennec/platform/interface/gfxcontext.h source/platform/interface/gfxcontext.cpp + include/fennec/platform/interface/gfxsurface.h source/platform/interface/gfxsurface.cpp + include/fennec/platform/interface/platform.h source/platform/interface/platform.cpp + include/fennec/platform/interface/window.h source/platform/interface/window.cpp ${FENNEC_EXTRA_SOURCES} - include/fennec/lang/type_operators.h - include/fennec/containers/tuple.h - include/fennec/containers/detail/__tuple.h - include/fennec/platform/linux/wayland/window.h - include/fennec/containers/list.h + include/fennec/platform/interface/inputdevice.h + include/fennec/core/event.h + source/core/event.cpp + include/fennec/concurrency/thread.h + include/fennec/concurrency/mutex.h + include/fennec/concurrency/atomic.h ) add_dependencies(fennec metaprogramming) diff --git a/PLANNING.md b/PLANNING.md index 964020a..c4a9a39 100644 --- a/PLANNING.md +++ b/PLANNING.md @@ -162,7 +162,6 @@ management would be used. Platform support will be implemented in the following order: - Linux/BSD - Wayland - - XKB - OpenGL (EGL) - PulseAudio - Vulkan diff --git a/cmake/build.cmake b/cmake/build.cmake index 020a9eb..5867d14 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -16,6 +16,8 @@ # along with this program. If not, see . # ====================================================================================================================== +# this script handles functionality related to the build process and its info + string(TOLOWER ${CMAKE_BUILD_TYPE} FENNEC_BUILD_NAME) message(STATUS "Build: ${FENNEC_BUILD_NAME}") diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index 1599f51..176966f 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -16,6 +16,8 @@ # along with this program. If not, see . # ====================================================================================================================== +# this script finds the compiler being used + if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") set(FENNEC_COMPILER "GCC") include("${FENNEC_SOURCE_DIR}/cmake/gcc.cmake") diff --git a/cmake/default_user.cmake b/cmake/default_user.cmake new file mode 100644 index 0000000..4b04d90 --- /dev/null +++ b/cmake/default_user.cmake @@ -0,0 +1,35 @@ +# ====================================================================================================================== +# 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 . +# ====================================================================================================================== + +# sets up cmake variables for client vs server +if(FENNEC_USER_CLIENT) + set(FENNEC_USER_CLIENT 1) + set(FENNEC_USER_SERVER 0) + + list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_USER_CLIENT=1) +elseif(FENNEC_USER_SERVER) + set(FENNEC_USER_CLIENT 0) + set(FENNEC_USER_SERVER 1) + + list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_USER_SERVER=1) +else() + set(FENNEC_USER_CLIENT 1) + set(FENNEC_USER_SERVER 0) + + list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_USER_CLIENT=1) +endif() \ No newline at end of file diff --git a/cmake/gcc.cmake b/cmake/gcc.cmake index 6e5a838..0450708 100644 --- a/cmake/gcc.cmake +++ b/cmake/gcc.cmake @@ -16,8 +16,10 @@ # along with this program. If not, see . # ====================================================================================================================== +# this script sets flags and variables for gnu and gnu-like compilers + add_compile_options("-mxsave" "-Wall" "-Wextra" "-pedantic" "-Werror") set(FENNEC_PRIVATE_LINK_OPTIONS "-nostdlib" "-fno-exceptions" "-fno-rtti" "-fdiagnostics-all-candidates") -list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_COMPILER_GCC=1) \ No newline at end of file +list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_COMPILER_GCC=1 FENNEC_NO_INLINE=[[gnu::noinline]]) \ No newline at end of file diff --git a/cmake/linux.cmake b/cmake/linux.cmake index dadf5f0..262bbe1 100644 --- a/cmake/linux.cmake +++ b/cmake/linux.cmake @@ -16,6 +16,7 @@ # along with this program. If not, see . # ====================================================================================================================== +# this script finds and loads libraries related to the Linux operating system. It also sets platform specific variables. macro(fennec_check_platform) # unix @@ -32,9 +33,10 @@ macro(fennec_check_platform) include/fennec/platform/linux/platform.h source/platform/linux/platform.cpp ) - # includes - include("${FENNEC_SOURCE_DIR}/cmake/wayland.cmake") + if(FENNEC_USER_CLIENT) + include("${FENNEC_SOURCE_DIR}/cmake/wayland.cmake") + + fennec_check_wayland() + endif() - # tests - fennec_check_wayland() endmacro() \ No newline at end of file diff --git a/cmake/opengl.cmake b/cmake/opengl.cmake new file mode 100644 index 0000000..cde9c63 --- /dev/null +++ b/cmake/opengl.cmake @@ -0,0 +1,48 @@ +# ====================================================================================================================== +# 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 . +# ====================================================================================================================== + +find_package(OpenGL) + +if(TARGET OpenGL::GL) # Core OpenGL Desktop Profile + list(APPEND FENNEC_LINK_LIBRARIES OpenGL::OpenGL) + list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_GRAPHICS_OPENGL=1) + +elseif(TARGET OpenGL::GLES3) # OpenGL for Embedded Systems 3 + list(APPEND FENNEC_LINK_LIBRARIES OpenGL::GLES3) + list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_GRAPHICS_GLES3=1) + +elseif (TARGET OpenGL::GLES2) # OpenGL for Embedded Systems 2 + list(APPEND FENNEC_LINK_LIBRARIES OpenGL::GLES2) + list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_GRAPHICS_GLES2=1) + +else() + message(FATAL_ERROR "No Suitable OpenGL implementation found.") +endif() + +if(FENNEC_GRAPHICS_WANT_EGL) + if(NOT TARGET OpenGL::EGL) + message(FATAL_ERROR "EGL Library not found.") + endif() + + list(APPEND FENNEC_LINK_LIBRARIES OpenGL::EGL) + list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_GRAPHICS_EGL=1) + list(APPEND FENNEC_EXTRA_SOURCES + include/fennec/platform/opengl/egl/context.h + include/fennec/platform/opengl/egl/surface.h + ) +endif() \ No newline at end of file diff --git a/cmake/platform.cmake b/cmake/platform.cmake index a73f1a3..24067c3 100644 --- a/cmake/platform.cmake +++ b/cmake/platform.cmake @@ -16,10 +16,19 @@ # along with this program. If not, see . # ====================================================================================================================== +# this script finds the operating system of the build environment + message(STATUS "OS: ${CMAKE_SYSTEM_NAME}") +include("${FENNEC_SOURCE_DIR}/cmake/default_user.cmake") + # Check for Linux if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(FENNEC_PLATFORM "Linux") include("${FENNEC_SOURCE_DIR}/cmake/linux.cmake") -endif () \ No newline at end of file +endif () + +# Graphics APIs +if(FENNEC_USER_CLIENT) + include("${FENNEC_SOURCE_DIR}/cmake/opengl.cmake") +endif() \ No newline at end of file diff --git a/cmake/unix.cmake b/cmake/unix.cmake index fb488ea..33385d5 100644 --- a/cmake/unix.cmake +++ b/cmake/unix.cmake @@ -16,6 +16,8 @@ # along with this program. If not, see . # ====================================================================================================================== +# generic unix functionality + # compile definitions list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_PLATFORM_UNIX=1 diff --git a/cmake/version.cmake b/cmake/version.cmake new file mode 100644 index 0000000..7f175d7 --- /dev/null +++ b/cmake/version.cmake @@ -0,0 +1,33 @@ +# ====================================================================================================================== +# 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 . +# ====================================================================================================================== + +# this script contains the main version + +set(FENNEC_VERSION_MAJOR 0) +set(FENNEC_VERSION_MINOR 1) +set(FENNEC_VERSION_PATCH 0) +set(FENNEC_VERSION_STRING "${FENNEC_VERSION_MAJOR}.${FENNEC_VERSION_MINOR}.${FENNEC_VERSION_PATCH}") +math(EXPR FENNEC_VERSION_NUM "(${FENNEC_VERSION_MAJOR} << 16) | (${FENNEC_VERSION_MINOR} << 8) | ${FENNEC_VERSION_PATCH}") + +list(APPEND FENNEC_COMPILE_DEFINITIONS + FENNEC_VERSION_MAJOR=${FENNEC_VERSION_MAJOR} + FENNEC_VERSION_MINOR=${FENNEC_VERSION_MINOR} + FENNEC_VERSION_PATCH=${FENNEC_VERSION_PATCH} + FENNEC_VERSION_STRING=${FENNEC_VERSION_STRING} + FENNEC_VERSION_NUM=${FENNEC_VERSION_NUM} +) \ No newline at end of file diff --git a/cmake/wayland.cmake b/cmake/wayland.cmake index da49b40..b0d940d 100644 --- a/cmake/wayland.cmake +++ b/cmake/wayland.cmake @@ -17,6 +17,7 @@ # ====================================================================================================================== # https://gist.github.com/mariobadr/acc3c8adf4b4e722705be38c3deac59a +# this script finds libwayland and dependencies macro(fennec_check_wayland) set(WAYLAND_CLIENT_FOUND 0) @@ -25,39 +26,55 @@ macro(fennec_check_wayland) WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h ) - find_library( WAYLAND_CLIENT_LIBRARY NAMES wayland-client libwayland-client ) - get_filename_component( - WAYLAND_CLIENT_LIBRARY - ${WAYLAND_CLIENT_LIBRARY} - NAME + + # EGL is required + find_path( + WAYLAND_EGL_INCLUDE_DIR + NAMES wayland-egl.h + ) + find_library( + WAYLAND_EGL_LIBRARY + NAMES wayland-egl libwayland-egl ) - if(WAYLAND_CLIENT_INCLUDE_DIR AND WAYLAND_CLIENT_LIBRARY) - set(WAYLAND_CLIENT_FOUND 1) - add_library(wayland::client UNKNOWN IMPORTED) - - set_target_properties( - wayland::client PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${WAYLAND_CLIENT_INCLUDE_DIR}" - IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${WAYLAND_CLIENT_LIBRARY}" + if( (WAYLAND_CLIENT_INCLUDE_DIR AND WAYLAND_CLIENT_LIBRARY) + AND (WAYLAND_EGL_INCLUDE_DIR AND WAYLAND_EGL_LIBRARY)) + get_filename_component( + WAYLAND_CLIENT_LIBRARY + ${WAYLAND_CLIENT_LIBRARY} + NAME ) + get_filename_component( + WAYLAND_EGL_LIBRARY + ${WAYLAND_EGL_LIBRARY} + NAME + ) + + set(WAYLAND_CLIENT_FOUND 1) + set(WAYLAND_EGL_FOUND 1) + set(FENNEC_GRAPHICS_WANT_EGL 1) list(APPEND FENNEC_EXTRA_SOURCES # 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_def.h + include/fennec/platform/linux/wayland/lib/wayland-client.h + include/fennec/platform/linux/wayland/lib/wayland-util.h include/fennec/platform/linux/wayland/lib/dyn.h source/platform/linux/wayland/lib/dyn.cpp # Fennec Files - include/fennec/platform/linux/wayland/display.h source/platform/linux/wayland/display.cpp + include/fennec/platform/linux/wayland/displaydev.h source/platform/linux/wayland/displaydev.cpp + include/fennec/platform/linux/wayland/window.h source/platform/linux/wayland/window.cpp ) - list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_LIB_WAYLAND="${WAYLAND_CLIENT_LIBRARY}") + list(APPEND FENNEC_COMPILE_DEFINITIONS + FENNEC_HAS_WAYLAND=1 + FENNEC_LIB_WAYLAND="${WAYLAND_CLIENT_LIBRARY}" + FENNEC_LIB_WAYLAND_EGL="${WAYLAND_EGL_LIBRARY}" + ) endif() endmacro() \ No newline at end of file diff --git a/doxy/Doxyfile b/doxy/Doxyfile index df913ab..26d134c 100644 --- a/doxy/Doxyfile +++ b/doxy/Doxyfile @@ -48,7 +48,7 @@ PROJECT_NAME = fennec # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.0.2 +PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/include/fennec/concurrency/atomic.h b/include/fennec/concurrency/atomic.h new file mode 100644 index 0000000..33b528b --- /dev/null +++ b/include/fennec/concurrency/atomic.h @@ -0,0 +1,22 @@ +// ===================================================================================================================== +// 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 . +// ===================================================================================================================== + +#ifndef FENNEC_CONCURRENCY_ATOMIC_H +#define FENNEC_CONCURRENCY_ATOMIC_H + +#endif // FENNEC_CONCURRENCY_ATOMIC_H diff --git a/include/fennec/concurrency/mutex.h b/include/fennec/concurrency/mutex.h new file mode 100644 index 0000000..94682da --- /dev/null +++ b/include/fennec/concurrency/mutex.h @@ -0,0 +1,22 @@ +// ===================================================================================================================== +// 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 . +// ===================================================================================================================== + +#ifndef FENNEC_CONCURRENCY_MUTEX_H +#define FENNEC_CONCURRENCY_MUTEX_H + +#endif // FENNEC_CONCURRENCY_MUTEX_H diff --git a/include/fennec/concurrency/thread.h b/include/fennec/concurrency/thread.h new file mode 100644 index 0000000..26814d2 --- /dev/null +++ b/include/fennec/concurrency/thread.h @@ -0,0 +1,22 @@ +// ===================================================================================================================== +// 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 . +// ===================================================================================================================== + +#ifndef FENNEC_CONCURRENCY_THREAD_H +#define FENNEC_CONCURRENCY_THREAD_H + +#endif // FENNEC_CONCURRENCY_THREAD_H diff --git a/include/fennec/containers/array.h b/include/fennec/containers/array.h index 0d78fe3..2cceb48 100644 --- a/include/fennec/containers/array.h +++ b/include/fennec/containers/array.h @@ -42,7 +42,9 @@ namespace fennec /// /// \brief wrapper for fixed size arrays /// -/// \details +/// \details | | | +/// |-|-| +/// | | | /// \tparam ValueT value type /// \tparam ElemV number of elements template @@ -78,6 +80,12 @@ struct array return elements[i]; } + constexpr ValueT* begin() { return elements; } + constexpr ValueT* end() { return elements + ElemV; } + + constexpr const ValueT* begin() const { return elements; } + constexpr const ValueT* end() const { return elements + ElemV; } + /// @} diff --git a/include/fennec/containers/dynarray.h b/include/fennec/containers/dynarray.h index fa0f1de..3d54f26 100644 --- a/include/fennec/containers/dynarray.h +++ b/include/fennec/containers/dynarray.h @@ -39,8 +39,7 @@ namespace fennec { template> -class dynarray -{ +class dynarray { public: using element_t = TypeT; using alloc_t = Alloc; @@ -95,6 +94,8 @@ public: } } + constexpr dynarray(size_t n, TypeT&&) = delete; + template constexpr dynarray(size_t n, ArgsT&&...args) { element_t* addr = _alloc.data(); @@ -130,6 +131,12 @@ public: assertd(i < _size, "Array Out of Bounds"); return _alloc.data()[i]; } + constexpr TypeT* begin() { return _alloc.data(); } + constexpr TypeT* end() { return begin() + _size; } + + constexpr const TypeT* begin() const { return _alloc; } + constexpr const TypeT* end() const { return begin() + _size; } + constexpr TypeT& back() { return this->operator[](size() - 1); } @@ -138,26 +145,6 @@ public: return this->operator[](size() - 1); } - constexpr void insert(size_t i, const TypeT& val) { - - // Grow if the size has reached the capacity of the allocation - if(_size == capacity()) { - _grow(); - } - - // Move the data if we are not inserting at the end of the array - if((i = min(i, _size)) < _size) { - fennec::memmove( - _alloc.data() + i - , _alloc.data() + i + 1 - , (_size - i) * sizeof(TypeT)); - } - - // Insert the element - fennec::construct(_alloc.data() + i, val); - ++_size; - } - constexpr void insert(size_t i, TypeT&& val) { // Grow if the size has reached the capacity of the allocation @@ -168,8 +155,8 @@ public: // Move the data if we are not inserting at the end of the array if((i = min(i, _size)) < _size) { fennec::memmove( - _alloc.data() + i + 1 - , _alloc.data() + i + (void*)(_alloc.data() + i + 1) + , (void*)(_alloc.data() + i) , (_size - i) * sizeof(TypeT)); } @@ -178,6 +165,26 @@ public: ++_size; } + constexpr void insert(size_t i, const TypeT& val) { + + // Grow if the size has reached the capacity of the allocation + if(_size == capacity()) { + _grow(); + } + + // Move the data if we are not inserting at the end of the array + if((i = min(i, _size)) < _size) { + fennec::memmove( + (void*)(_alloc.data() + i) + , (void*)(_alloc.data() + i + 1) + , (_size - i) * sizeof(TypeT)); + } + + // Insert the element + fennec::construct(_alloc.data() + i, val); + ++_size; + } + template constexpr void emplace(size_t i, ArgsT&&...args) { @@ -189,8 +196,8 @@ public: // Move the data if we are not inserting at the end of the array if((i = min(i, _size)) < _size) { fennec::memmove( - _alloc.data() + i - , _alloc.data() + i + 1 + (void*)(_alloc.data() + i) + , (void*)(_alloc.data() + i + 1) , (_size - i) * sizeof(TypeT)); } @@ -208,7 +215,7 @@ public: } constexpr void pop_back() { - _alloc[_size--].~TypeT(); + fennec::destruct(&_alloc[_size--]); } template @@ -218,6 +225,15 @@ public: constexpr void resize(size_t n) { _alloc.reallocate(n); + + if (_size < n) { + _size = n; + return; + } + + while (_size < n) { + emplace_back(); + } } private: diff --git a/include/fennec/containers/list.h b/include/fennec/containers/list.h index b458c17..ce3fc67 100644 --- a/include/fennec/containers/list.h +++ b/include/fennec/containers/list.h @@ -20,9 +20,14 @@ #define FENNEC_CONTAINERS_LIST_H #include +#include #include #include +#include + +#include + namespace fennec { @@ -33,6 +38,8 @@ public: using value_t = TypeT; static constexpr size_t npos = -1; + class iterator; + private: struct node { optional data; @@ -82,20 +89,21 @@ private: return n; } - size_t _next_free(size_t i) { + size_t _next_free() { if (not _freed.empty()) { size_t n = _freed.back(); _freed.pop_back(); return n; } _table[_size]; + return _size; } public: using elem_t = node; constexpr list() - : _table(), _root(npos), _last(npos), _freed(), _size(0) { + : _table(), _freed(), _root(npos), _last(npos), _size(0) { } constexpr ~list() = default; @@ -108,14 +116,14 @@ public: assertd(i >= 0, "Index out of Bounds"); size_t n = _walk(i); assertd(n != npos, "Index out of Bounds"); - return _table[n].data; + return *_table[n].data; } constexpr const value_t& operator[](int i) const { assertd(i >= 0, "Index out of Bounds"); size_t n = _walk(i); assertd(n != npos, "Index out of Bounds"); - return _table[n].data; + return *_table[n].data; } void insert(size_t i, value_t&& x) { @@ -123,20 +131,25 @@ public: if (size() == capacity()) { _expand(); } - size_t n = _walk(min(i, size() - 1)); - size_t p = _next_free(i); + size_t n = _walk(min(i, size_t(size() - 1))); + size_t p = _next_free(); if (n == npos) { _root = p; _table[p].data = fennec::forward(x); + _table[p].next = npos; + _table[p].prev = npos; return; } _table[p].data = fennec::forward(x); - _table[p].next = n; - _table[p].prev = _prev(p); - _table[n].prev = p; + if (i == size()) { + _table[p].next = n; + _table[p].prev = _prev(n); + _table[n].prev = p; + } + else { + _table[p].prev = n; + } ++_size; - - _last = (n == npos) ? p : _last; } void insert(size_t i, const value_t& x) { @@ -175,8 +188,9 @@ public: // Fix prev and next nodes if (p != npos) _table[p].next = n; + else _root = n; if (n != npos) _table[n].prev = p; - else _last = j; + else _last = p; // Mark node as freed _freed.push_back(j); @@ -190,11 +204,75 @@ public: erase(_size - 1); } + constexpr value_t& back() { + return this->operator[](size() - 1); + } + + constexpr const value_t& back() const { + return this->operator[](size() - 1); + } + +// ITERATOR ============================================================================================================ + + class iterator { + public: + ~iterator() { + _list = nullptr; + } + + // prefix operator + constexpr friend iterator& operator++(iterator& rhs) { + if (rhs._list->_next(rhs._n) < rhs._list->capacity()) { + return rhs; + } + rhs._n = npos; + return rhs; + } + + constexpr friend iterator operator++(iterator& lhs, int) { + iterator prev = lhs; + ++lhs; + return prev; + } + + constexpr value_t& operator*() { + return *(_list->_table[_n].data); + } + + constexpr bool operator==(const iterator& it) { + return _list == it._list and _n == it._n; + } + + constexpr bool operator!=(const iterator& it) { + return _list != it._list or _n != it._n; + } + + private: + list* _list; + size_t _n; + friend list; + + iterator(list* ls, size_t n) + : _list(ls) + , _n(n) { + } + }; + + constexpr iterator begin() { + return iterator(this, _root); + } + + constexpr iterator end() { + return iterator(this, npos); + } + private: allocation _table; dynarray _freed; size_t _root, _last, _size; + friend class iterator; + constexpr void _expand() { _table.reallocate(_table.capacity() * 2); } diff --git a/include/fennec/containers/map.h b/include/fennec/containers/map.h index 34aca16..fc41edc 100644 --- a/include/fennec/containers/map.h +++ b/include/fennec/containers/map.h @@ -77,7 +77,7 @@ public: pair val; ~U() { - root.~pair(); + fennec::destruct(&root); } } trick = { .root = { key, 0 } }; auto it = _set.find(trick.val); @@ -93,7 +93,7 @@ public: pair val; ~U() { - root.~pair(); + fennec::destruct(&root); } } trick = { .root = { key, 0 } }; // Only initialize root auto it = _set.find(trick.val); @@ -110,7 +110,7 @@ public: pair val; ~U() { - root.~pair(); + fennec::destruct(&root); } } trick = { .root = { key_t(fennec::forward(args)...), 0 } }; // Only initialize root auto it = _set.find(trick.val); @@ -127,7 +127,7 @@ public: pair val; ~U() { - root.~pair(); + fennec::destruct(&root); } } trick = { .root = { key_t(fennec::forward(args)...), 0 } }; // Only initialize root auto it = _set.find(trick.val); @@ -157,7 +157,7 @@ public: pair val; ~U() { - root.~pair(); + fennec::destruct(&root); } } trick = { .root = { fennec::forward(key), 0 } }; _set.erase(trick.val); @@ -175,7 +175,7 @@ public: pair val; ~U() { - root.~pair(); + fennec::destruct(&root); } } trick = { .root = { KeyT(fennec::forward(args)...), 0 } }; _set.erase(trick.val); diff --git a/include/fennec/containers/optional.h b/include/fennec/containers/optional.h index 0be5898..5498cc4 100644 --- a/include/fennec/containers/optional.h +++ b/include/fennec/containers/optional.h @@ -40,9 +40,9 @@ struct optional { public: // Constructors ======================================================================================================== using reference_t = T&; - using pointer_t = add_pointer_t>; - using const_reference_t = const T&; - using const_pointer_t = const add_pointer_t>; + using pointer_t = T*; + using const_reference_t = T&; + using const_pointer_t = const T*; /// /// \brief Default Constructor @@ -61,7 +61,7 @@ public: /// /// \brief Fundamental Type Constructor /// \param val the value to initialize the underlying object with - constexpr optional(T val) requires is_fundamental_v + constexpr optional(T val) requires(is_fundamental_v or is_pointer_v) : _val(val) , _set(true) { } @@ -102,7 +102,7 @@ public: return; } if (_set) { - _val.~T(); + fennec::destruct(&_val); } } @@ -115,7 +115,7 @@ public: constexpr optional& operator=(nullopt_t) { if constexpr(not is_fundamental_v) { if (_set) { - _val.~T(); + fennec::destruct(&_val); } } _root = '\0'; @@ -158,7 +158,7 @@ public: if (_set) { // Construct fennec::construct(&_val, opt._val); } else { // Destruct - _val.~T(); + fennec::destruct(&_val); _root = 0; } } else if (_set) { // Copy Assignment @@ -176,7 +176,7 @@ public: if (_set) { // Construct fennec::construct(&_val, fennec::move(opt._val)); } else { // Destruct - _val.~T(); + fennec::destruct(&_val); _root = 0; } } else if (_set) { // Copy Assignment @@ -211,7 +211,7 @@ public: return _set ? &_val : nullptr; } - constexpr const pointer_t operator->() const noexcept { + constexpr const_pointer_t operator->() const noexcept { return _set ? &_val : nullptr; } diff --git a/include/fennec/containers/set.h b/include/fennec/containers/set.h index f406788..57a2c38 100644 --- a/include/fennec/containers/set.h +++ b/include/fennec/containers/set.h @@ -238,19 +238,14 @@ public: class iterator { public: - constexpr iterator(const set* set, size_t i) - : _set(set) - , _i(i) { - } - constexpr ~iterator() { _set = nullptr; } // prefix operator constexpr friend iterator& operator++(iterator& rhs) { - while (++rhs._i < capacity()) { - if (rhs._set->_alloc[rhs._i]) { + while (++rhs._i < rhs._set->capacity()) { + if (rhs._set->_alloc[rhs._i].value) { return rhs; } } @@ -280,6 +275,11 @@ public: const set* _set; size_t _i; friend set; + + constexpr iterator(const set* set, size_t i) + : _set(set) + , _i(i) { + } }; constexpr iterator begin() const { diff --git a/include/fennec/core/engine.h b/include/fennec/core/engine.h index e51393c..aca7f49 100644 --- a/include/fennec/core/engine.h +++ b/include/fennec/core/engine.h @@ -51,8 +51,9 @@ /// /// | Library | Brief | /// | :------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -/// | \subpage fennec_lang | Implementation for functions and classes related to the C++ Language, including base types, common utility functions, and metaprogramming templates | -/// | \subpage fennec_math | Implementation of math functions according to the [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf). Additional extensions are provided for other common math functions. | +/// | \subpage fennec_lang | Implementation for functions and classes related to the C++ Language, including base types, common utility functions, and metaprogramming templates | +/// | \subpage fennec_math | Implementation of math functions according to the [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf). Additional extensions are provided for other common math functions. | +/// | \subpage fennec_memory | Implementation of functions related to memory management. | #ifndef FENNEC_CORE_ENGINE_H #define FENNEC_CORE_ENGINE_H diff --git a/include/fennec/core/event.h b/include/fennec/core/event.h new file mode 100644 index 0000000..4ccd1a0 --- /dev/null +++ b/include/fennec/core/event.h @@ -0,0 +1,61 @@ +// ===================================================================================================================== +// 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 . +// ===================================================================================================================== + +#ifndef FENNEC_CORE_EVENT_H +#define FENNEC_CORE_EVENT_H + +#include +#include + +namespace fennec +{ + +struct event; + +class event_listener { +public: + virtual ~event_listener() = default; + virtual void handle_event(event* event) = 0; +}; + +struct event { + const uint64_t type; + + event() = delete; + + template + event() : type(typeuuid()) { } + + template + static void add_listener(event_listener* listener) { + event::add_listener(listener, typeuuid()); + } + + template + static void dispatch(EventT* event) { + dispatch(event); + } + + static void add_listener(event_listener* listener, uint64_t type); + static void remove_listener(event_listener* listener); + static void dispatch(event* event); +}; + +} + +#endif // FENNEC_CORE_EVENT_H diff --git a/include/fennec/fproc/filesystem/path.h b/include/fennec/fproc/filesystem/path.h index 774c711..2b4675a 100644 --- a/include/fennec/fproc/filesystem/path.h +++ b/include/fennec/fproc/filesystem/path.h @@ -149,7 +149,7 @@ public: bool empty() { size_t size = _str.size(); if (size == 0) return true; -#ifdef _WIN32 +#if FENNEC_PLATFORM_WINDOWS return (_str[1] == ':' && size == 3); #else return (_str[0] == '/' && size == 1); @@ -157,7 +157,7 @@ public: } path parent() const { -#ifdef _WIN32 +#ifdef FENNEC_PLATFORM_WINDOWS size_t start = _str.size() - 1; start = _str[start] == '/' || _str[start] == '\\' ? start - 1 : start; @@ -185,7 +185,7 @@ public: path working; working._str.resize(0); // Check if this is a rooted path; -#ifdef _WIN32 +#ifdef FENNEC_PLATFORM_WINDOWS if (_str[1] != ':') { #else if (_str[0] != '/') { diff --git a/include/fennec/fproc/strings/cstring.h b/include/fennec/fproc/strings/cstring.h index 9392066..b26f2d2 100644 --- a/include/fennec/fproc/strings/cstring.h +++ b/include/fennec/fproc/strings/cstring.h @@ -67,6 +67,12 @@ public: : _str(nullptr), _size(0), _const(true) { } + /// + /// \brief Default Constructor, initializes with nullptr + constexpr cstring(nullptr_t) + : _str(nullptr), _size(0), _const(true) { + } + /// /// \brief Buffer Constructor, wraps the provided C-Style string /// \param str the buffer to wrap @@ -129,11 +135,16 @@ public: constexpr cstring(const cstring&) = delete; constexpr ~cstring() = default; + constexpr cstring& operator=(nullptr_t) { + _str = nullptr, _size = 0, _const = true; + return *this; + } + // TODO: Document template constexpr cstring& operator=(char(&str)[n]) { assert(_str[n - 1] == '\0', "Invalid NTBS."); - _str = str; _size = n - 1; _const = false; + _str = str, _size = n - 1, _const = false; return *this; } @@ -160,6 +171,10 @@ public: /// \returns the size of the string excluding its null terminator, i.e. `(*str)[size()] == '\0'` constexpr size_t size() const { return _size; } + constexpr bool empty() const { + return _cstr == nullptr || _size == 0; + } + // Access ============================================================================================================== @@ -220,6 +235,15 @@ public: return ::strncmp(_cstr + i, str, n); } + /// + /// \brief String Equality + /// \param str the string to compare against + /// \returns True if all characters are equal, false otherwise + template + constexpr bool operator==(const char (&str)[n]) const { + return compare(cstring(str)) == 0; + } + /// /// \brief String Equality /// \param str the string to compare against diff --git a/include/fennec/fproc/strings/string.h b/include/fennec/fproc/strings/string.h index 8ff8d89..9c15a83 100644 --- a/include/fennec/fproc/strings/string.h +++ b/include/fennec/fproc/strings/string.h @@ -78,18 +78,6 @@ public: fennec::memset(_str.data(), c, n); _str[n] = '\0'; } - /// - /// \brief Buffer Copy Constructor - /// \param str the buffer to copy - /// \tparam 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 `len` is the intended number of characters. - template - constexpr _string(const char str[n]) - : _str(str, n + 1) { - _str[n] = '\0'; - } /// /// \brief Buffer Copy Constructor @@ -327,6 +315,10 @@ public: /// \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'; diff --git a/include/fennec/fproc/strings/wcstring.h b/include/fennec/fproc/strings/wcstring.h index fce3b33..facb3a0 100644 --- a/include/fennec/fproc/strings/wcstring.h +++ b/include/fennec/fproc/strings/wcstring.h @@ -71,6 +71,12 @@ public: , _const(true) { } + /// + /// \brief Default Constructor, initializes with nullptr + constexpr wcstring(nullptr_t) + : _str(nullptr), _size(0), _const(true) { + } + /// /// \brief Buffer Constructor, wraps the provided C-Style string /// \param str the buffer to wrap @@ -133,6 +139,11 @@ public: constexpr wcstring(const wcstring&) = delete; constexpr ~wcstring() = default; + constexpr wcstring& operator=(nullptr_t) { + _str = nullptr, _size = 0, _const = true; + return *this; + } + // TODO: Document template constexpr wcstring& operator=(wchar_t(&str)[n]) { @@ -164,6 +175,10 @@ public: /// \returns the size of the string excluding its null terminator, i.e. `(*str)[size()] == '\0'` constexpr size_t size() const { return _size; } + constexpr bool empty() const { + return _cstr == nullptr || _size == 0; + } + // Access ============================================================================================================== diff --git a/include/fennec/fproc/strings/wstring.h b/include/fennec/fproc/strings/wstring.h index a7139fd..893ebc8 100644 --- a/include/fennec/fproc/strings/wstring.h +++ b/include/fennec/fproc/strings/wstring.h @@ -59,45 +59,32 @@ public: } /// - /// \brief Sized Constructor, initializes a null-terminated string of size `n` with null wchar_tacters - /// \param n the number of wchar_tacters + /// \brief Sized Constructor, initializes a null-terminated string of size `n` with null characters + /// \param n the number of characters /// - /// \details adds additional wchar_tacter for null termination. + /// \details adds additional character for null termination. constexpr _wstring(size_t n) : _wstring('\0', n) { } /// - /// \brief Sized Constructor, initializes a null-terminated string of size `n` filled with the wchar_tacter `c` - /// \param c the wchar_tacter to fill with - /// \param n the number of wchar_tacters + /// \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 wchar_tacter for null termination. + /// \details adds additional character for null termination. constexpr _wstring(wchar_t c, size_t n) : _str(n + 1) { fennec::wmemset(_str.data(), c, n); _str[n] = '\0'; } - /// - /// \brief Buffer Copy Constructor - /// \param str the buffer to copy - /// \param len number of wchar_tacters in the buffer - /// - /// \details adds additional wchar_tacter for null termination. Ignores whether str is null-terminated. - /// This constructor makes the assumption that `len` is the intended number of wchar_tacters. - template - constexpr _wstring(const wchar_t str[n]) - : _str(str, n + 1) { - ::wcsncpy(_str.data(), str, n); - _str[n] = '\0'; - } /// /// \brief Buffer Copy Constructor /// \param str the buffer to copy - /// \param len number of wchar_tacters in the buffer + /// \param len number of characters in the buffer /// - /// \details adds additional wchar_tacter for null termination. Ignores whether str is null-terminated. - /// This constructor makes the assumption that `len` is the intended number of wchar_tacters. + /// \details adds additional character for null termination. Ignores whether str is null-terminated. + /// This constructor makes the assumption that `len` is the intended number of characters. constexpr _wstring(const wchar_t* str, size_t n) : _str(str, n + 1) { ::wcsncpy(_str.data(), str, n); @@ -107,10 +94,10 @@ public: /// /// \brief Buffer Copy Constructor /// \param str the buffer to copy - /// \param len number of wchar_tacters in the buffer + /// \param len number of characters in the buffer /// - /// \details adds additional wchar_tacter for null termination. Ignores whether str is null-terminated. - /// This constructor makes the assumption that `len` is the intended number of wchar_tacters. + /// \details adds additional character for null termination. Ignores whether str is null-terminated. + /// This constructor makes the assumption that `len` is the intended number of characters. constexpr _wstring(const wcstring& str) : _str(str, str.size() + 1) { _str[str.size()] = '\0'; @@ -149,7 +136,7 @@ public: /// /// \brief Array Access Operator /// \param i the index to access - /// \returns a reference to the wchar_tacter + /// \returns a reference to the character constexpr wchar_t& operator[](int i) { return _str[i]; } @@ -157,7 +144,7 @@ public: /// /// \brief Const-Array Access Operator /// \param i the index to access - /// \returns a copy of the wchar_tacter + /// \returns a copy of the character constexpr wchar_t operator[](int i) const { assertd(i >= 0 && i < size(), "Array Out of Bounds"); return _str[i]; @@ -219,7 +206,7 @@ public: /// /// \brief Finds the index of the first occurrence of `c` in the string - /// \param c the wchar_tacter to find + /// \param c the character to find /// \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 { if (i >= size()) { // bounds check @@ -332,6 +319,10 @@ public: /// \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'; @@ -361,7 +352,7 @@ public: /// /// \brief Retrieve a substring of a string /// \param i the start index - /// \param n the number of wchar_tacters + /// \param n the number of characters /// \return constexpr wstring substring(size_t i, size_t n = npos) const { if (i >= size()) { @@ -378,7 +369,7 @@ public: constexpr wstring operator+(wchar_t c) const { // Copy contents with one additional byte. wstring res(_str, _str.size()); - res[size()] = c; // Set the last wchar_tacter to c + res[size()] = c; // Set the last character to c return res; } diff --git a/include/fennec/lang/assert.h b/include/fennec/lang/assert.h index ee305a7..eefcdd5 100644 --- a/include/fennec/lang/assert.h +++ b/include/fennec/lang/assert.h @@ -64,7 +64,7 @@ /// /// -#if _MSC_VER +#if FENNEC_COMPILER_MSVC #define __PRETTY_FUNCTION__ __FUNCSIG__ #endif diff --git a/include/fennec/lang/constants.h b/include/fennec/lang/constants.h index 562fa5c..1535ed4 100644 --- a/include/fennec/lang/constants.h +++ b/include/fennec/lang/constants.h @@ -31,6 +31,8 @@ #ifndef FENNEC_LANG_CONSTANTS_H #define FENNEC_LANG_CONSTANTS_H +#include + /// /// /// \page fennec_lang_constants Constants @@ -61,8 +63,6 @@ /// /// -#include - namespace fennec { diff --git a/include/fennec/lang/detail/__int.h b/include/fennec/lang/detail/__int.h index 601ea4a..f9a3917 100644 --- a/include/fennec/lang/detail/__int.h +++ b/include/fennec/lang/detail/__int.h @@ -19,7 +19,7 @@ #ifndef FENNEC_LANG_DETAIL_INT_H #define FENNEC_LANG_DETAIL_INT_H -#if _MSC_VER +#if FENNEC_COMPILER_MSVC #pragma warning(push) #pragma warning(disable:4117) diff --git a/include/fennec/platform/linux/wayland/lib/sym_def.h b/include/fennec/lang/detail/__typeuuid.h similarity index 70% rename from include/fennec/platform/linux/wayland/lib/sym_def.h rename to include/fennec/lang/detail/__typeuuid.h index 74e03fe..d0469e6 100644 --- a/include/fennec/platform/linux/wayland/lib/sym_def.h +++ b/include/fennec/lang/detail/__typeuuid.h @@ -16,12 +16,20 @@ // along with this program. If not, see . // ===================================================================================================================== -#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_SYM_DEF_H -#define FENNEC_PLATFORM_LINUX_WAYLAND_SYM_DEF_H +#ifndef FENNEC_LANG_DETAIL_TYPEUUID_H +#define FENNEC_LANG_DETAIL_TYPEUUID_H -#define FENNEC_LIB(name) inline bool FENNEC_HAS_LIB_##name = false; -#define FENNEC_SYMBOL(ret, fn, ...) using sym_##fn = ret(*)(__VA_ARGS__); \ - inline sym_##fn fn = nullptr; -#include +#include -#endif // FENNEC_PLATFORM_LINUX_WAYLAND_SYM_DEF_H +namespace fennec::detail +{ + +template +FENNEC_NO_INLINE uint64_t __typeuuid() { + static uint64_t i = 0; + return ++i; +} + +} + +#endif // FENNEC_LANG_DETAIL_TYPEUUID_H diff --git a/include/fennec/lang/hashing.h b/include/fennec/lang/hashing.h index 75050bf..40a2e62 100644 --- a/include/fennec/lang/hashing.h +++ b/include/fennec/lang/hashing.h @@ -54,8 +54,10 @@ struct hash : hash { // Wrapper for pointers template - requires is_pointer_v -struct hash : hash { +struct hash : hash { + constexpr size_t operator()(PtrT* ptr) const { + return hash::operator()((uintptr_t)(const void*)ptr); + } }; // Float diff --git a/include/fennec/lang/intrinsics.h b/include/fennec/lang/intrinsics.h index b71bfec..8008688 100644 --- a/include/fennec/lang/intrinsics.h +++ b/include/fennec/lang/intrinsics.h @@ -251,7 +251,7 @@ // TODO: More compiler support -#if _MSC_VER +#if FENNEC_COMPILER_MSVC # define FENNEC_HAS_BUILTIN_ADDRESS_OF 1 # define FENNEC_BUILTIN_ADDRESS_OF(arg) __builtin_addressof(arg) diff --git a/include/fennec/lang/type_traits.h b/include/fennec/lang/type_traits.h index a5c79d2..12d99f4 100644 --- a/include/fennec/lang/type_traits.h +++ b/include/fennec/lang/type_traits.h @@ -119,6 +119,14 @@ template auto declval() noexcept -> decltype(detail::__declval(0) return detail::__declval(0); } +constexpr inline bool is_constant_evaluated() noexcept { + if consteval { + return true; + } else { + return false; + } +} + // fennec::is_void ===================================================================================================== diff --git a/include/fennec/lang/types.h b/include/fennec/lang/types.h index 734f635..18bb5ec 100644 --- a/include/fennec/lang/types.h +++ b/include/fennec/lang/types.h @@ -263,15 +263,15 @@ namespace fennec /// \name Sized Integer Types /// @{ - using int8_t = schar_t; ///< \brief Signed 8-bit integer - using int16_t = short_t; ///< \brief Signed 16-bit integer - using int32_t = conditional_t; ///< \brief Signed 32-bit integer - using int64_t = conditional_t; ///< \brief Signed 64-bit integer + using int8_t = ::int8_t; ///< \brief Signed 8-bit integer + using int16_t = ::int16_t; ///< \brief Signed 16-bit integer + using int32_t = ::int32_t; ///< \brief Signed 32-bit integer + using int64_t = ::int64_t; ///< \brief Signed 64-bit integer - using uint8_t = uchar_t; ///< \brief Unsigned 8-bit integer - using uint16_t = ushort_t; ///< \brief Unsigned 16-bit integer - using uint32_t = conditional_t; ///< \brief Unsigned 32-bit integer - using uint64_t = conditional_t; ///< \brief Unsigned 64-bit integer + using uint8_t = ::uint8_t; ///< \brief Unsigned 8-bit integer + using uint16_t = ::uint16_t; ///< \brief Unsigned 16-bit integer + using uint32_t = ::uint32_t; ///< \brief Unsigned 32-bit integer + using uint64_t = ::uint64_t; ///< \brief Unsigned 64-bit integer /// @} diff --git a/include/fennec/lang/typeuuid.h b/include/fennec/lang/typeuuid.h new file mode 100644 index 0000000..6d46f6d --- /dev/null +++ b/include/fennec/lang/typeuuid.h @@ -0,0 +1,47 @@ +// ===================================================================================================================== +// 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 . +// ===================================================================================================================== + +#ifndef FENNEC_LANG_TYPEUUID_H +#define FENNEC_LANG_TYPEUUID_H + +#include +#include +#include + +#include + +namespace fennec +{ + +constexpr uint64_t nullid = 0; + +template +FENNEC_NO_INLINE uint64_t typeuuid() { + assertf(not is_constant_evaluated(), "Type UUIDs Cannot Be Obtained at Compile Time"); + + static bool init = false; + static uint64_t id = nullid; + + if (init) return id; + init = true; + return id = detail::__typeuuid(); +} + +} + +#endif // FENNEC_LANG_TYPEUUID_H diff --git a/include/fennec/math/common.h b/include/fennec/math/common.h index 84eb5c6..3addc92 100644 --- a/include/fennec/math/common.h +++ b/include/fennec/math/common.h @@ -275,7 +275,7 @@ #include -#if _MSC_VER +#if FENNEC_COMPILER_MSVC #define isnanf(x) isnan(x) #define isinff(x) isinf(x) #endif diff --git a/include/fennec/math/ext/constants.h b/include/fennec/math/ext/constants.h index 9ae1a32..8866e86 100644 --- a/include/fennec/math/ext/constants.h +++ b/include/fennec/math/ext/constants.h @@ -531,7 +531,7 @@ /// /// -#if _MSC_VER +#if FENNEC_COMPILER_MSVC #pragma warning(push) #pragma warning(disable:4305) #endif diff --git a/include/fennec/math/vector_storage.h b/include/fennec/math/vector_storage.h index e3c634b..b8225ed 100644 --- a/include/fennec/math/vector_storage.h +++ b/include/fennec/math/vector_storage.h @@ -25,7 +25,7 @@ #pragma GCC diagnostic ignored "-Wpedantic" #endif -#if _MSC_VER +#if FENNEC_COMPILER_MSVC #pragma warning(push) #pragma warning(disable:4201) #endif @@ -606,7 +606,7 @@ namespace fennec::detail } -#ifdef __GNUC__ +#ifdef FENNEC_COMPILER_GCC #pragma GCC diagnostic pop #endif diff --git a/include/fennec/memory/allocator.h b/include/fennec/memory/allocator.h index fcbbceb..662985c 100644 --- a/include/fennec/memory/allocator.h +++ b/include/fennec/memory/allocator.h @@ -44,7 +44,7 @@ #include -#ifdef __GNUC__ +#ifdef FENNEC_COMPILER_GCC #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wchanges-meaning" #endif @@ -302,20 +302,20 @@ public: /// /// \brief Default Constructor, initializes internal data to `null` and the capacity to `0` constexpr allocation() noexcept - : _data(nullptr), _capacity(0) { + : _data(nullptr), _capacity(0), _alignment(zero()) { } /// /// \brief Sized Constructor, initializes the allocation with a block of size `n * sizeof(T)` bytes /// \param n The number of elements of type `T` to allocate for - constexpr allocation(size_t n) noexcept - : _data(nullptr), _capacity(0) { + explicit constexpr allocation(size_t n) noexcept + : _data(nullptr), _capacity(0), _alignment(zero()) { allocate(n); } /// /// \brief Buffer Copy Constructor, initializes the allocation with a block of size `n * sizeof(T)` bytes. - /// Then, the contents of data are copied into the allocation. + /// Then, the contents of data are byte copied into the allocation. /// \param data the buffer to copy /// \param n the number of elements constexpr allocation(const T* data, size_t n) @@ -330,13 +330,13 @@ public: constexpr allocation(size_t n, align_t align) noexcept : _data(nullptr) , _capacity(0) - , _alignment(zero()) { + , _alignment(align) { allocate(n, align); } /// /// \brief Buffer Copy Constructor, initializes the allocation with a block of size `n * sizeof(T)` bytes. - /// Then, the contents of data are copied into the allocation. + /// Then, the contents of data are byte copied into the allocation. /// \param data the buffer to copy /// \param n the number of elements /// \param align The alignment of the allocation @@ -350,10 +350,11 @@ public: /// \param alloc The allocation object to copy. /// /// \details This constructor should be used when the type `AllocT` needs internal data. - constexpr allocation(const alloc_t& alloc) noexcept + explicit constexpr allocation(const alloc_t& alloc) noexcept : _alloc(alloc) , _data(nullptr) - , _capacity(0) { + , _capacity(0) + , _alignment(zero()){ } /// @@ -417,7 +418,8 @@ public: constexpr allocation(const allocation& alloc) noexcept : _alloc(alloc._alloc) , _data(_alloc.allocate(alloc._capacity)) - , _capacity(alloc._capacity) { + , _capacity(alloc._capacity) + , _alignment(alloc._alignment) { fennec::memcpy(_data, alloc._data, alloc._capacity * sizeof(T)); } @@ -428,7 +430,8 @@ public: constexpr allocation(allocation&& alloc) noexcept : _alloc(alloc._alloc) , _data(alloc._data) - , _capacity(alloc._capacity) { + , _capacity(alloc._capacity) + , _alignment(alloc._alignment) { alloc._data = nullptr; alloc._capacity = 0; } @@ -524,7 +527,7 @@ public: value_t* old = _data; _data = _alloc.allocate(n); - fennec::memcpy(_data, old, min(_capacity, n) * sizeof(T)); + fennec::memcpy(static_cast(_data), old, min(_capacity, n) * sizeof(T)); _alloc.deallocate(old); _capacity = n; } @@ -591,7 +594,7 @@ private: align_t _alignment; // Alignment information }; -#ifdef __GNUC__ +#ifdef FENNEC_COMPILER_GCC #pragma GCC diagnostic pop #endif diff --git a/include/fennec/memory/bytes.h b/include/fennec/memory/bytes.h index b0be033..eaaf262 100644 --- a/include/fennec/memory/bytes.h +++ b/include/fennec/memory/bytes.h @@ -67,7 +67,7 @@ public: /// \param arr the buffer to wrap /// \tparam n the size of the buffer in elements template - constexpr byte_array(T arr[n]) + constexpr byte_array(T (&arr)[n]) : byte_array(arr, n * sizeof(T)) { } @@ -76,7 +76,7 @@ public: /// \param arr the buffer to wrap /// \tparam n the size of the buffer in elements template - constexpr byte_array(const T arr[n]) + constexpr byte_array(const T (&arr)[n]) : byte_array(arr, n * sizeof(T)) { } diff --git a/include/fennec/memory/detail/__string.h b/include/fennec/memory/detail/__string.h index 3e829ff..648d253 100644 --- a/include/fennec/memory/detail/__string.h +++ b/include/fennec/memory/detail/__string.h @@ -23,14 +23,14 @@ // see https://git.mslockbo.org/mslockbo/fennec/src/commit/0eeb7ae3cff9d78e98dc5d9fc09bcb98b10986b9 for previous // implementation -#if __GNUC__ +#if FENNEC_COMPILER_GCC #define __OPTIMIZE__ #endif #include #include -#if __GNUC__ +#if FENNEC_COMPILER_GCC #undef __OPTIMIZE__ #endif diff --git a/include/fennec/memory/new.h b/include/fennec/memory/new.h index df5f762..3581006 100644 --- a/include/fennec/memory/new.h +++ b/include/fennec/memory/new.h @@ -101,5 +101,8 @@ void operator delete[](void* ptr, fennec::size_t, fennec::align_t) noexcept; void operator delete (void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept; void operator delete[](void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept; +template constexpr void* operator new (fennec::size_t, TypeT* ptr) { return ptr; } +template constexpr void* operator new[](fennec::size_t, TypeT* ptr) { return ptr; } + #endif // FENNEC_MEMORY_NEW_H diff --git a/include/fennec/platform/interface/displaydev.h b/include/fennec/platform/interface/displaydev.h new file mode 100644 index 0000000..67e6763 --- /dev/null +++ b/include/fennec/platform/interface/displaydev.h @@ -0,0 +1,71 @@ +// ===================================================================================================================== +// 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 . +// ===================================================================================================================== + +#ifndef FENNEC_PLATFORM_INTERFACE_DISPLAYDEV_H +#define FENNEC_PLATFORM_INTERFACE_DISPLAYDEV_H + +#include +#include + +namespace fennec +{ + +/// +/// \brief Interface for display management +class displaydev +{ +public: + struct pixel_format { + uint8_t depth; + uint8_t r, g, b; + }; + + struct config { + pixel_format format; + }; + + virtual bool connected() const = 0; + virtual ~displaydev() = default; + + virtual window* create_window() = 0; + + const pixel_format& get_color_format() const { + return _config.format; + } + + template + ContextT* get_context() { + return static_cast(_context); + } + + template + PlatformT* get_platform() { + return static_cast(_platform); + } + +protected: + platform* _platform; + gfxcontext* _context; + config _config; + + displaydev(platform* platform); +}; + +} + +#endif // FENNEC_PLATFORM_INTERFACE_DISPLAYDEV_H diff --git a/include/fennec/platform/interface/fwd.h b/include/fennec/platform/interface/fwd.h index 3e6b3a6..623532b 100644 --- a/include/fennec/platform/interface/fwd.h +++ b/include/fennec/platform/interface/fwd.h @@ -22,8 +22,11 @@ namespace fennec { +class platform; class window; -class display; +class displaydev; +class gfxcontext; +class gfxsurface; } diff --git a/include/fennec/platform/interface/display.h b/include/fennec/platform/interface/gfxcontext.h similarity index 77% rename from include/fennec/platform/interface/display.h rename to include/fennec/platform/interface/gfxcontext.h index c1ec968..14d8da8 100644 --- a/include/fennec/platform/interface/display.h +++ b/include/fennec/platform/interface/gfxcontext.h @@ -16,30 +16,28 @@ // along with this program. If not, see . // ===================================================================================================================== -#ifndef FENNEC_PLATFORM_INTERFACE_DISPLAY_H -#define FENNEC_PLATFORM_INTERFACE_DISPLAY_H +#ifndef FENNEC_PLATFORM_INTERFACE_GFXCONTEXT_H +#define FENNEC_PLATFORM_INTERFACE_GFXCONTEXT_H #include namespace fennec { -/// -/// \brief Interface for display management -class display -{ +class gfxcontext { public: - struct config { + template + TypeT* get_device() { + return static_cast(_device); + } - }; - - virtual bool connected() const = 0; - virtual ~display() = default; +protected: + gfxcontext(displaydev* device); private: - config _config; + displaydev* _device; }; } -#endif // FENNEC_PLATFORM_INTERFACE_DISPLAY_H +#endif // FENNEC_PLATFORM_INTERFACE_GFXCONTEXT_H diff --git a/include/fennec/platform/interface/gfxsurface.h b/include/fennec/platform/interface/gfxsurface.h new file mode 100644 index 0000000..9aa49aa --- /dev/null +++ b/include/fennec/platform/interface/gfxsurface.h @@ -0,0 +1,48 @@ +// ===================================================================================================================== +// 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 . +// ===================================================================================================================== + +#ifndef FENNEC_PLATFORM_INTERFACE_GFXSURFACE_H +#define FENNEC_PLATFORM_INTERFACE_GFXSURFACE_H + +#include + +namespace fennec +{ + +class gfxsurface { + template + ContextT* get_context() { + return static_cast(_context); + } + + template + WindowT* get_window() { + return static_cast(_window); + } + +protected: + gfxsurface(window* window, gfxcontext* context); + +private: + window* _window; + gfxcontext* _context; +}; + +} + +#endif // FENNEC_PLATFORM_INTERFACE_GFXSURFACE_H diff --git a/include/fennec/platform/linux/wayland/display.h b/include/fennec/platform/interface/inputdevice.h similarity index 63% rename from include/fennec/platform/linux/wayland/display.h rename to include/fennec/platform/interface/inputdevice.h index ac14abe..136bef5 100644 --- a/include/fennec/platform/linux/wayland/display.h +++ b/include/fennec/platform/interface/inputdevice.h @@ -16,31 +16,21 @@ // along with this program. If not, see . // ===================================================================================================================== -#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H -#define FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H - -#include -#include - -#include -#include +#ifndef FENNEC_PLATFORM_INTERFACE_INPUTDEVICE_H +#define FENNEC_PLATFORM_INTERFACE_INPUTDEVICE_H namespace fennec { -class wayland_display : public display { +class inputdevice { public: - wayland_display(linux_platform* platform); - wayland_display(linux_platform* platform, const cstring& drv); - ~wayland_display() override; - - bool connected() const override; + virtual bool has_keyboard() = 0; + virtual bool has_mouse() = 0; + virtual bool has_touch() = 0; private: - struct wl_display* _handle; - linux_platform* _platform; }; } -#endif // FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H +#endif // FENNEC_PLATFORM_INTERFACE_INPUTDEVICE_H diff --git a/include/fennec/platform/interface/platform.h b/include/fennec/platform/interface/platform.h index 084fcac..3ea1412 100644 --- a/include/fennec/platform/interface/platform.h +++ b/include/fennec/platform/interface/platform.h @@ -29,19 +29,14 @@ class platform { public: using shared_object = struct shared_object; using function_pointer = void (*)(void); + using global = void*; struct shared_lib { shared_object* _lib; const cstring _name; }; - enum class user { - client, - server - }; - struct config { - user type; }; // Functions with default implementations @@ -52,17 +47,18 @@ public: // Pure Virtual Functions - virtual display* get_display() = 0; + virtual displaydev* get_display() = 0; virtual shared_object* load_object(const cstring& file) = 0; virtual void unload_object(shared_object* obj) = 0; virtual function_pointer find_symbol(shared_object* hndl, const cstring& name) = 0; + virtual global find_global(shared_object* hndl, const cstring& name) = 0; protected: - platform(user t); + platform(); virtual ~platform() = default; private: diff --git a/include/fennec/platform/interface/window.h b/include/fennec/platform/interface/window.h index 2f09bbe..2845ca7 100644 --- a/include/fennec/platform/interface/window.h +++ b/include/fennec/platform/interface/window.h @@ -19,8 +19,10 @@ #ifndef FENNEC_PLATFORM_INTERFACE_WINDOW_H #define FENNEC_PLATFORM_INTERFACE_WINDOW_H +#include #include #include +#include namespace fennec { @@ -45,19 +47,18 @@ public: flags_block_screensaver = 0x1 << 4, }; - union bits { - uint32_t depth; - uint8_t r, g, b, a; - }; - struct config { string title; uint32_t flags; size_t width, height; fullscreen_mode fullscreen; - bits bit_depth; }; + virtual bool running() = 0; + virtual void configure(const config& config) = 0; + virtual bool initialize(bool modal) = 0; + virtual bool shutdown() = 0; + virtual bool set_title(const cstring& title) = 0; virtual bool set_title(const string& title) = 0; @@ -74,60 +75,76 @@ public: virtual bool block_screensaver(bool e) = 0; bool is_child() const { - return _config.flags & flags_child; + if (not _config) return false; + return _config->flags & flags_child; } bool is_modal() const { - return _config.flags & flags_modal; + if (not _config) return false; + return _config->flags & flags_modal; } - display* get_display() { + displaydev* get_display() { return _display; } - const display* get_display() const { + const displaydev* get_display() const { return _display; } const string& get_title() const { - return _config.title; + static const string _null = { "null" }; + if (not _config) return _null; + return _config->title; } size_t get_width() const { - return _config.width; + if (not _config) return false; + return _config->width; } size_t get_height() const { - return _config.height; + if (not _config) return false; + return _config->height; } fullscreen_mode get_fullscreen_mode() const { - return _config.fullscreen; + if (not _config) return fullscreen_mode::windowed; + return _config->fullscreen; } bool is_keyboard_grabbed() const { - return _config.flags & flags_grab_keyboard; + if (not _config) return false; + return _config->flags & flags_grab_keyboard; } bool is_mouse_grabbed() const { - return _config.flags & flags_grab_mouse; + if (not _config) return false; + return _config->flags & flags_grab_mouse; } bool is_screensaver_blocked() const { - return _config.flags & flags_block_screensaver; + if (not _config) return false; + return _config->flags & flags_block_screensaver; + } + + template + DisplayT* get_display() { + return static_cast(_display); } protected: virtual ~window() = default; - window(display* display, window* parent, bool modal); + window(displaydev* display, window* parent); - display* _display; - window* _parent; - config _config; + displaydev* _display; + window* _parent; + optional _config; + gfxsurface* _context; private: }; diff --git a/include/fennec/platform/linux/platform.h b/include/fennec/platform/linux/platform.h index 7813e5a..7bfcfac 100644 --- a/include/fennec/platform/linux/platform.h +++ b/include/fennec/platform/linux/platform.h @@ -20,7 +20,7 @@ #define FENNEC_PLATFORM_LINUX_PLATFORM_H #include -#include +#include #include namespace fennec @@ -34,18 +34,20 @@ public: display_wayland, }; - linux_platform(user type); + linux_platform(); ~linux_platform() override; shared_object* load_object(const cstring& file) override; - void unload_object(shared_object* obj) override; - function_pointer find_symbol(shared_object* hndl, const cstring& name) override; + void unload_object(shared_object* obj) override; - display* get_display() override; + function_pointer find_symbol(shared_object* hndl, const cstring& name) override; + global find_global(shared_object* hndl, const cstring& name) override; + + displaydev* get_display() override; private: - display* _display; + displaydev* _display; int_t _display_driver; void _runtime_client_checks(); diff --git a/include/fennec/platform/linux/wayland/displaydev.h b/include/fennec/platform/linux/wayland/displaydev.h new file mode 100644 index 0000000..69f833d --- /dev/null +++ b/include/fennec/platform/linux/wayland/displaydev.h @@ -0,0 +1,71 @@ +// ===================================================================================================================== +// 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 . +// ===================================================================================================================== + +#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H +#define FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H + +#include +#include + +#include + +#include +#include +#include + +namespace fennec +{ + +class wayland_display : public displaydev { +public: + wayland_display(linux_platform* platform); + wayland_display(linux_platform* platform, const cstring& drv); + ~wayland_display() override; + + bool connected() const override; + + window* create_window() override; + + inline wl_display* get_handle() { return _handle; } + inline wl_registry* get_registry() { return _registry; } + inline wl_compositor* get_compositor() { return _compositor; } + inline wl_shell* get_shell() { return _shell; } + inline wl_seat* get_seat() { return _seat; } + inline wl_pointer* get_pointer() { return _pointer; } + inline wl_keyboard* get_keyboard() { return _keyboard; } + inline wl_shm* get_shm() { return _shm; } + +private: + wl_display* _handle; + wl_registry* _registry; + wl_compositor* _compositor; + wl_shell* _shell; + wl_seat* _seat; + wl_pointer* _pointer; + wl_keyboard* _keyboard; + wl_shm* _shm; + list _windows; + + static void listen_global(void*, wl_registry*, uint32_t, const char*, uint32_t); + static void listen_global_remove(void*, wl_registry*, uint32_t); + static void listen_seat(void*, wl_seat*, uint32_t); +}; + +} + +#endif // FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H diff --git a/include/fennec/platform/linux/wayland/fwd.h b/include/fennec/platform/linux/wayland/fwd.h new file mode 100644 index 0000000..6a5ccc9 --- /dev/null +++ b/include/fennec/platform/linux/wayland/fwd.h @@ -0,0 +1,30 @@ +// ===================================================================================================================== +// fennec, a free and open source game engine +// Copyright © 2025 Medusa Slockbower +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ===================================================================================================================== + +#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_FWD_H +#define FENNEC_PLATFORM_LINUX_WAYLAND_FWD_H + +namespace fennec +{ + +class wayland_display; +class wayland_window; + +} + +#endif // FENNEC_PLATFORM_LINUX_WAYLAND_FWD_H diff --git a/include/fennec/platform/linux/wayland/lib/fwd.h b/include/fennec/platform/linux/wayland/lib/fwd.h index 59e9e97..0590366 100644 --- a/include/fennec/platform/linux/wayland/lib/fwd.h +++ b/include/fennec/platform/linux/wayland/lib/fwd.h @@ -16,9 +16,46 @@ // along with this program. If not, see . // ===================================================================================================================== -#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_FWD_H -#define FENNEC_PLATFORM_LINUX_WAYLAND_FWD_H +#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_LIB_FWD_H +#define FENNEC_PLATFORM_LINUX_WAYLAND_LIB_FWD_H +#include +#include + +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; -#endif // FENNEC_PLATFORM_LINUX_WAYLAND_FWD_H +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 diff --git a/include/fennec/platform/linux/wayland/lib/sym.h b/include/fennec/platform/linux/wayland/lib/sym.h index a851bca..838592c 100644 --- a/include/fennec/platform/linux/wayland/lib/sym.h +++ b/include/fennec/platform/linux/wayland/lib/sym.h @@ -16,6 +16,7 @@ // along with this program. If not, see . // ===================================================================================================================== +#include #include #ifndef FENNEC_LIB @@ -26,12 +27,87 @@ #define FENNEC_SYMBOL(...) #endif +#ifndef FENNEC_GLOBAL +#define FENNEC_GLOBAL(...) +#endif + + FENNEC_LIB(WAYLAND); -FENNEC_SYMBOL(struct wl_display*, wl_display_connect, const char* name); -FENNEC_SYMBOL(void, wl_display_disconnect, wl_display* name); +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_create, struct wl_proxy*, const struct wl_interface*); +FENNEC_SYMBOL(void, wl_proxy_destroy, struct wl_proxy*); +FENNEC_SYMBOL(int, wl_proxy_add_listener, struct wl_proxy*, void (**)(void), void*); +FENNEC_SYMBOL(void, wl_proxy_set_user_data, struct wl_proxy*, void*); +FENNEC_SYMBOL(void*, wl_proxy_get_user_data, struct wl_proxy*); +FENNEC_SYMBOL(uint32_t, wl_proxy_get_version, struct wl_proxy*); +FENNEC_SYMBOL(uint32_t, wl_proxy_get_id, struct wl_proxy*); +FENNEC_SYMBOL(const char*, wl_proxy_get_class, struct wl_proxy*); +FENNEC_SYMBOL(void, wl_proxy_set_queue, struct wl_proxy*, struct wl_event_queue*); +FENNEC_SYMBOL(void*, wl_proxy_create_wrapper, void*); +FENNEC_SYMBOL(void, wl_proxy_wrapper_destroy, void*); +FENNEC_SYMBOL(struct wl_display*, wl_display_connect, const char*); +FENNEC_SYMBOL(struct wl_display*, wl_display_connect_to_fd, int); +FENNEC_SYMBOL(void, wl_display_disconnect, struct wl_display*); +FENNEC_SYMBOL(int, wl_display_get_fd, struct wl_display*); +FENNEC_SYMBOL(int, wl_display_dispatch, struct wl_display*); +FENNEC_SYMBOL(int, wl_display_dispatch_queue, struct wl_display*, struct wl_event_queue*); +FENNEC_SYMBOL(int, wl_display_dispatch_queue_pending, struct wl_display*, struct wl_event_queue*); +FENNEC_SYMBOL(int, wl_display_dispatch_pending, struct wl_display*); +FENNEC_SYMBOL(int, wl_display_prepare_read, struct wl_display*); +FENNEC_SYMBOL(int, wl_display_prepare_read_queue, struct wl_display*, struct wl_event_queue*); +FENNEC_SYMBOL(int, wl_display_read_events, struct wl_display*); +FENNEC_SYMBOL(void, wl_display_cancel_read, struct wl_display*); +FENNEC_SYMBOL(int, wl_display_get_error, struct wl_display*); +FENNEC_SYMBOL(int, wl_display_flush, struct wl_display*); +FENNEC_SYMBOL(int, wl_display_roundtrip, struct wl_display*); +FENNEC_SYMBOL(struct wl_event_queue*, wl_display_create_queue, struct wl_display*); +FENNEC_SYMBOL(void, wl_event_queue_destroy, struct wl_event_queue*); +FENNEC_SYMBOL(void, wl_log_set_handler_client, wl_log_func_t); +FENNEC_SYMBOL(void, wl_list_init, struct wl_list*); +FENNEC_SYMBOL(void, wl_list_insert, struct wl_list*, struct wl_list*) ; +FENNEC_SYMBOL(void, wl_list_remove, struct wl_list*); +FENNEC_SYMBOL(int, wl_list_length, const struct wl_list*); +FENNEC_SYMBOL(int, wl_list_empty, const struct wl_list*); +FENNEC_SYMBOL(void, wl_list_insert_list, struct wl_list*, struct wl_list*); +FENNEC_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_registry_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_callback_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_compositor_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_shm_pool_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_shm_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_buffer_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_data_offer_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_data_source_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_data_device_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_data_device_manager_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_shell_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_shell_surface_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_surface_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_seat_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_pointer_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_keyboard_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_touch_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_output_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_region_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_subcompositor_interface); +FENNEC_GLOBAL(const struct wl_interface, wl_subsurface_interface); + +FENNEC_LIB(WAYLAND_EGL); + +FENNEC_SYMBOL(struct wl_egl_window*, wl_egl_window_create, struct wl_surface *surface, int width, int height); +FENNEC_SYMBOL(void, wl_egl_window_destroy, struct wl_egl_window *egl_window); +FENNEC_SYMBOL(void, wl_egl_window_resize, struct wl_egl_window *egl_window, int width, int height, int dx, int dy); +FENNEC_SYMBOL(void, wl_egl_window_get_attached_size, struct wl_egl_window *egl_window, int *width, int *height); #undef FENNEC_LIB #undef FENNEC_SYMBOL +#undef FENNEC_GLOBAL diff --git a/include/fennec/platform/linux/wayland/lib/wayland-client.h b/include/fennec/platform/linux/wayland/lib/wayland-client.h new file mode 100644 index 0000000..ce9c40b --- /dev/null +++ b/include/fennec/platform/linux/wayland/lib/wayland-client.h @@ -0,0 +1,2004 @@ +// ===================================================================================================================== +// 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 . +// ===================================================================================================================== + +#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_SYM_DEF_H +#define FENNEC_PLATFORM_LINUX_WAYLAND_SYM_DEF_H + +#define FENNEC_LIB(name) inline bool FENNEC_HAS_LIB_##name = false; +#define FENNEC_SYMBOL(ret, fn, ...) using sym_##fn = ret(*)(__VA_ARGS__); \ + inline sym_##fn fn = nullptr; +#define FENNEC_GLOBAL(type, name) inline type* name = nullptr; +#include + +#include +#include +#include +#include + +/* + * 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 WL_DISPLAY_ERROR_ENUM +#define WL_DISPLAY_ERROR_ENUM +enum wl_display_error { + WL_DISPLAY_ERROR_INVALID_OBJECT = 0, + WL_DISPLAY_ERROR_INVALID_METHOD = 1, + WL_DISPLAY_ERROR_NO_MEMORY = 2, + WL_DISPLAY_ERROR_IMPLEMENTATION = 3, +}; +#endif /* WL_DISPLAY_ERROR_ENUM */ + +struct wl_display_listener { + void (*error)(void *data, + struct wl_display *wl_display, + void *object_id, + uint32_t code, + const char *message); + + void (*delete_id)(void *data, + struct wl_display *wl_display, + uint32_t id); +}; + +static inline int +wl_display_add_listener(struct wl_display *wl_display, + const struct wl_display_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_display, + (void (**)(void)) listener, data); +} + +#define WL_DISPLAY_SYNC 0 +#define WL_DISPLAY_GET_REGISTRY 1 + +static inline void +wl_display_set_user_data(struct wl_display *wl_display, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_display, user_data); +} + +static inline void * +wl_display_get_user_data(struct wl_display *wl_display) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_display); +} + +static inline uint32_t +wl_display_get_version(struct wl_display *wl_display) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_display); +} + +static inline struct wl_callback * +wl_display_sync(struct wl_display *wl_display) +{ + struct wl_proxy *callback; + + callback = wl_proxy_marshal_flags((struct wl_proxy *) wl_display, + WL_DISPLAY_SYNC, wl_callback_interface, wl_proxy_get_version((struct wl_proxy *) wl_display), 0, NULL); + + return (struct wl_callback *) callback; +} + +static inline struct wl_registry * +wl_display_get_registry(struct wl_display *wl_display) +{ + struct wl_proxy *registry; + + registry = wl_proxy_marshal_flags((struct wl_proxy *) wl_display, + WL_DISPLAY_GET_REGISTRY, wl_registry_interface, wl_proxy_get_version((struct wl_proxy *) wl_display), 0, NULL); + + return (struct wl_registry *) registry; +} + +struct wl_registry_listener { + + void (*global)(void *data, + struct wl_registry *wl_registry, + uint32_t name, + const char *interface, + uint32_t version); + + void (*global_remove)(void *data, + struct wl_registry *wl_registry, + uint32_t name); +}; + +static inline int +wl_registry_add_listener(struct wl_registry *wl_registry, + const struct wl_registry_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_registry, + (void (**)(void)) listener, data); +} + +#define WL_REGISTRY_BIND 0 + +static inline void +wl_registry_set_user_data(struct wl_registry *wl_registry, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_registry, user_data); +} + +static inline void * +wl_registry_get_user_data(struct wl_registry *wl_registry) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_registry); +} + +static inline uint32_t +wl_registry_get_version(struct wl_registry *wl_registry) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_registry); +} + +static inline void +wl_registry_destroy(struct wl_registry *wl_registry) +{ + wl_proxy_destroy((struct wl_proxy *) wl_registry); +} + +static inline void * +wl_registry_bind(struct wl_registry *wl_registry, uint32_t name, const struct wl_interface *interface, uint32_t version) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_registry, + WL_REGISTRY_BIND, interface, version, 0, name, interface->name, version, NULL); + + return (void *) id; +} + +struct wl_callback_listener { + /** + * done event + * + * Notify the client when the related request is done. + * @param callback_data request-specific data for the callback + */ + void (*done)(void *data, + struct wl_callback *wl_callback, + uint32_t callback_data); +}; + +static inline int +wl_callback_add_listener(struct wl_callback *wl_callback, + const struct wl_callback_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_callback, + (void (**)(void)) listener, data); +} + +static inline void +wl_callback_set_user_data(struct wl_callback *wl_callback, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_callback, user_data); +} + +static inline void * +wl_callback_get_user_data(struct wl_callback *wl_callback) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_callback); +} + +static inline uint32_t +wl_callback_get_version(struct wl_callback *wl_callback) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_callback); +} + +/** @ingroup iface_wl_callback */ +static inline void +wl_callback_destroy(struct wl_callback *wl_callback) +{ + wl_proxy_destroy((struct wl_proxy *) wl_callback); +} + +#define WL_COMPOSITOR_CREATE_SURFACE 0 +#define WL_COMPOSITOR_CREATE_REGION 1 + +static inline void +wl_compositor_set_user_data(struct wl_compositor *wl_compositor, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_compositor, user_data); +} + +/** @ingroup iface_wl_compositor */ +static inline void * +wl_compositor_get_user_data(struct wl_compositor *wl_compositor) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_compositor); +} + +static inline uint32_t +wl_compositor_get_version(struct wl_compositor *wl_compositor) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_compositor); +} + +/** @ingroup iface_wl_compositor */ +static inline void +wl_compositor_destroy(struct wl_compositor *wl_compositor) +{ + wl_proxy_destroy((struct wl_proxy *) wl_compositor); +} + +static inline struct wl_surface * +wl_compositor_create_surface(struct wl_compositor *wl_compositor) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_compositor, + WL_COMPOSITOR_CREATE_SURFACE, wl_surface_interface, wl_proxy_get_version((struct wl_proxy *) wl_compositor), 0, NULL); + + return (struct wl_surface *) id; +} + +static inline struct wl_region * +wl_compositor_create_region(struct wl_compositor *wl_compositor) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_compositor, + WL_COMPOSITOR_CREATE_REGION, wl_region_interface, wl_proxy_get_version((struct wl_proxy *) wl_compositor), 0, NULL); + + return (struct wl_region *) id; +} + +#define WL_SHM_POOL_CREATE_BUFFER 0 +#define WL_SHM_POOL_DESTROY 1 +#define WL_SHM_POOL_RESIZE 2 + +static inline void +wl_shm_pool_set_user_data(struct wl_shm_pool *wl_shm_pool, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_shm_pool, user_data); +} + +static inline void * +wl_shm_pool_get_user_data(struct wl_shm_pool *wl_shm_pool) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_shm_pool); +} + +static inline uint32_t +wl_shm_pool_get_version(struct wl_shm_pool *wl_shm_pool) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_shm_pool); +} + +static inline struct wl_buffer * +wl_shm_pool_create_buffer(struct wl_shm_pool *wl_shm_pool, int32_t offset, int32_t width, int32_t height, int32_t stride, uint32_t format) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_shm_pool, + WL_SHM_POOL_CREATE_BUFFER, wl_buffer_interface, wl_proxy_get_version((struct wl_proxy *) wl_shm_pool), 0, NULL, offset, width, height, stride, format); + + return (struct wl_buffer *) id; +} + +static inline void +wl_shm_pool_destroy(struct wl_shm_pool *wl_shm_pool) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shm_pool, + WL_SHM_POOL_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shm_pool), WL_MARSHAL_FLAG_DESTROY); +} + +static inline void +wl_shm_pool_resize(struct wl_shm_pool *wl_shm_pool, int32_t size) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shm_pool, + WL_SHM_POOL_RESIZE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shm_pool), 0, size); +} + +#ifndef WL_SHM_ERROR_ENUM +#define WL_SHM_ERROR_ENUM +enum wl_shm_error { + WL_SHM_ERROR_INVALID_FORMAT = 0, + WL_SHM_ERROR_INVALID_STRIDE = 1, + WL_SHM_ERROR_INVALID_FD = 2, +}; +#endif /* WL_SHM_ERROR_ENUM */ + +#ifndef WL_SHM_FORMAT_ENUM +#define WL_SHM_FORMAT_ENUM +enum wl_shm_format { + WL_SHM_FORMAT_ARGB8888 = 0, + WL_SHM_FORMAT_XRGB8888 = 1, + WL_SHM_FORMAT_C8 = 0x20203843, + WL_SHM_FORMAT_RGB332 = 0x38424752, + WL_SHM_FORMAT_BGR233 = 0x38524742, + WL_SHM_FORMAT_XRGB4444 = 0x32315258, + WL_SHM_FORMAT_XBGR4444 = 0x32314258, + WL_SHM_FORMAT_RGBX4444 = 0x32315852, + WL_SHM_FORMAT_BGRX4444 = 0x32315842, + WL_SHM_FORMAT_ARGB4444 = 0x32315241, + WL_SHM_FORMAT_ABGR4444 = 0x32314241, + WL_SHM_FORMAT_RGBA4444 = 0x32314152, + WL_SHM_FORMAT_BGRA4444 = 0x32314142, + WL_SHM_FORMAT_XRGB1555 = 0x35315258, + WL_SHM_FORMAT_XBGR1555 = 0x35314258, + WL_SHM_FORMAT_RGBX5551 = 0x35315852, + WL_SHM_FORMAT_BGRX5551 = 0x35315842, + WL_SHM_FORMAT_ARGB1555 = 0x35315241, + WL_SHM_FORMAT_ABGR1555 = 0x35314241, + WL_SHM_FORMAT_RGBA5551 = 0x35314152, + WL_SHM_FORMAT_BGRA5551 = 0x35314142, + WL_SHM_FORMAT_RGB565 = 0x36314752, + WL_SHM_FORMAT_BGR565 = 0x36314742, + WL_SHM_FORMAT_RGB888 = 0x34324752, + WL_SHM_FORMAT_BGR888 = 0x34324742, + WL_SHM_FORMAT_XBGR8888 = 0x34324258, + WL_SHM_FORMAT_RGBX8888 = 0x34325852, + WL_SHM_FORMAT_BGRX8888 = 0x34325842, + WL_SHM_FORMAT_ABGR8888 = 0x34324241, + WL_SHM_FORMAT_RGBA8888 = 0x34324152, + WL_SHM_FORMAT_BGRA8888 = 0x34324142, + WL_SHM_FORMAT_XRGB2101010 = 0x30335258, + WL_SHM_FORMAT_XBGR2101010 = 0x30334258, + WL_SHM_FORMAT_RGBX1010102 = 0x30335852, + WL_SHM_FORMAT_BGRX1010102 = 0x30335842, + WL_SHM_FORMAT_ARGB2101010 = 0x30335241, + WL_SHM_FORMAT_ABGR2101010 = 0x30334241, + WL_SHM_FORMAT_RGBA1010102 = 0x30334152, + WL_SHM_FORMAT_BGRA1010102 = 0x30334142, + WL_SHM_FORMAT_YUYV = 0x56595559, + WL_SHM_FORMAT_YVYU = 0x55595659, + WL_SHM_FORMAT_UYVY = 0x59565955, + WL_SHM_FORMAT_VYUY = 0x59555956, + WL_SHM_FORMAT_AYUV = 0x56555941, + WL_SHM_FORMAT_NV12 = 0x3231564e, + WL_SHM_FORMAT_NV21 = 0x3132564e, + WL_SHM_FORMAT_NV16 = 0x3631564e, + WL_SHM_FORMAT_NV61 = 0x3136564e, + WL_SHM_FORMAT_YUV410 = 0x39565559, + WL_SHM_FORMAT_YVU410 = 0x39555659, + WL_SHM_FORMAT_YUV411 = 0x31315559, + WL_SHM_FORMAT_YVU411 = 0x31315659, + WL_SHM_FORMAT_YUV420 = 0x32315559, + WL_SHM_FORMAT_YVU420 = 0x32315659, + WL_SHM_FORMAT_YUV422 = 0x36315559, + WL_SHM_FORMAT_YVU422 = 0x36315659, + WL_SHM_FORMAT_YUV444 = 0x34325559, + WL_SHM_FORMAT_YVU444 = 0x34325659, + WL_SHM_FORMAT_R8 = 0x20203852, + WL_SHM_FORMAT_R16 = 0x20363152, + WL_SHM_FORMAT_RG88 = 0x38384752, + WL_SHM_FORMAT_GR88 = 0x38385247, + WL_SHM_FORMAT_RG1616 = 0x32334752, + WL_SHM_FORMAT_GR1616 = 0x32335247, + WL_SHM_FORMAT_XRGB16161616F = 0x48345258, + WL_SHM_FORMAT_XBGR16161616F = 0x48344258, + WL_SHM_FORMAT_ARGB16161616F = 0x48345241, + WL_SHM_FORMAT_ABGR16161616F = 0x48344241, + WL_SHM_FORMAT_XYUV8888 = 0x56555958, + WL_SHM_FORMAT_VUY888 = 0x34325556, + WL_SHM_FORMAT_VUY101010 = 0x30335556, + WL_SHM_FORMAT_Y210 = 0x30313259, + WL_SHM_FORMAT_Y212 = 0x32313259, + WL_SHM_FORMAT_Y216 = 0x36313259, + WL_SHM_FORMAT_Y410 = 0x30313459, + WL_SHM_FORMAT_Y412 = 0x32313459, + WL_SHM_FORMAT_Y416 = 0x36313459, + WL_SHM_FORMAT_XVYU2101010 = 0x30335658, + WL_SHM_FORMAT_XVYU12_16161616 = 0x36335658, + WL_SHM_FORMAT_XVYU16161616 = 0x38345658, + WL_SHM_FORMAT_Y0L0 = 0x304c3059, + WL_SHM_FORMAT_X0L0 = 0x304c3058, + WL_SHM_FORMAT_Y0L2 = 0x324c3059, + WL_SHM_FORMAT_X0L2 = 0x324c3058, + WL_SHM_FORMAT_YUV420_8BIT = 0x38305559, + WL_SHM_FORMAT_YUV420_10BIT = 0x30315559, + WL_SHM_FORMAT_XRGB8888_A8 = 0x38415258, + WL_SHM_FORMAT_XBGR8888_A8 = 0x38414258, + WL_SHM_FORMAT_RGBX8888_A8 = 0x38415852, + WL_SHM_FORMAT_BGRX8888_A8 = 0x38415842, + WL_SHM_FORMAT_RGB888_A8 = 0x38413852, + WL_SHM_FORMAT_BGR888_A8 = 0x38413842, + WL_SHM_FORMAT_RGB565_A8 = 0x38413552, + WL_SHM_FORMAT_BGR565_A8 = 0x38413542, + WL_SHM_FORMAT_NV24 = 0x3432564e, + WL_SHM_FORMAT_NV42 = 0x3234564e, + WL_SHM_FORMAT_P210 = 0x30313250, + WL_SHM_FORMAT_P010 = 0x30313050, + WL_SHM_FORMAT_P012 = 0x32313050, + WL_SHM_FORMAT_P016 = 0x36313050, + WL_SHM_FORMAT_AXBXGXRX106106106106 = 0x30314241, + WL_SHM_FORMAT_NV15 = 0x3531564e, + WL_SHM_FORMAT_Q410 = 0x30313451, + WL_SHM_FORMAT_Q401 = 0x31303451, + WL_SHM_FORMAT_XRGB16161616 = 0x38345258, + WL_SHM_FORMAT_XBGR16161616 = 0x38344258, + WL_SHM_FORMAT_ARGB16161616 = 0x38345241, + WL_SHM_FORMAT_ABGR16161616 = 0x38344241, + WL_SHM_FORMAT_C1 = 0x20203143, + WL_SHM_FORMAT_C2 = 0x20203243, + WL_SHM_FORMAT_C4 = 0x20203443, + WL_SHM_FORMAT_D1 = 0x20203144, + WL_SHM_FORMAT_D2 = 0x20203244, + WL_SHM_FORMAT_D4 = 0x20203444, + WL_SHM_FORMAT_D8 = 0x20203844, + WL_SHM_FORMAT_R1 = 0x20203152, + WL_SHM_FORMAT_R2 = 0x20203252, + WL_SHM_FORMAT_R4 = 0x20203452, + WL_SHM_FORMAT_R10 = 0x20303152, + WL_SHM_FORMAT_R12 = 0x20323152, + WL_SHM_FORMAT_AVUY8888 = 0x59555641, + WL_SHM_FORMAT_XVUY8888 = 0x59555658, + WL_SHM_FORMAT_P030 = 0x30333050, +}; +#endif /* WL_SHM_FORMAT_ENUM */ + +struct wl_shm_listener { + + void (*format)(void *data, + struct wl_shm *wl_shm, + uint32_t format); +}; + +static inline int +wl_shm_add_listener(struct wl_shm *wl_shm, + const struct wl_shm_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_shm, + (void (**)(void)) listener, data); +} + +#define WL_SHM_CREATE_POOL 0 +#define WL_SHM_RELEASE 1 + +static inline void +wl_shm_set_user_data(struct wl_shm *wl_shm, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_shm, user_data); +} + +static inline void * +wl_shm_get_user_data(struct wl_shm *wl_shm) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_shm); +} + +static inline uint32_t +wl_shm_get_version(struct wl_shm *wl_shm) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_shm); +} + +static inline void +wl_shm_destroy(struct wl_shm *wl_shm) +{ + wl_proxy_destroy((struct wl_proxy *) wl_shm); +} + +static inline struct wl_shm_pool * +wl_shm_create_pool(struct wl_shm *wl_shm, int32_t fd, int32_t size) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_shm, + WL_SHM_CREATE_POOL, wl_shm_pool_interface, wl_proxy_get_version((struct wl_proxy *) wl_shm), 0, NULL, fd, size); + + return (struct wl_shm_pool *) id; +} + +static inline void +wl_shm_release(struct wl_shm *wl_shm) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shm, + WL_SHM_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shm), WL_MARSHAL_FLAG_DESTROY); +} + +struct wl_buffer_listener { + + void (*release)(void *data, + struct wl_buffer *wl_buffer); +}; + +static inline int +wl_buffer_add_listener(struct wl_buffer *wl_buffer, + const struct wl_buffer_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_buffer, + (void (**)(void)) listener, data); +} + +#define WL_BUFFER_DESTROY 0 + +static inline void +wl_buffer_set_user_data(struct wl_buffer *wl_buffer, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_buffer, user_data); +} + +static inline void * +wl_buffer_get_user_data(struct wl_buffer *wl_buffer) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_buffer); +} + +static inline uint32_t +wl_buffer_get_version(struct wl_buffer *wl_buffer) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_buffer); +} + +static inline void +wl_buffer_destroy(struct wl_buffer *wl_buffer) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_buffer, + WL_BUFFER_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_buffer), WL_MARSHAL_FLAG_DESTROY); +} + +#ifndef WL_DATA_OFFER_ERROR_ENUM +#define WL_DATA_OFFER_ERROR_ENUM +enum wl_data_offer_error { + WL_DATA_OFFER_ERROR_INVALID_FINISH = 0, + WL_DATA_OFFER_ERROR_INVALID_ACTION_MASK = 1, + WL_DATA_OFFER_ERROR_INVALID_ACTION = 2, + WL_DATA_OFFER_ERROR_INVALID_OFFER = 3, +}; +#endif /* WL_DATA_OFFER_ERROR_ENUM */ + +struct wl_data_offer_listener { + + void (*offer)(void *data, + struct wl_data_offer *wl_data_offer, + const char *mime_type); + + void (*source_actions)(void *data, + struct wl_data_offer *wl_data_offer, + uint32_t source_actions); + + void (*action)(void *data, + struct wl_data_offer *wl_data_offer, + uint32_t dnd_action); +}; + +static inline int +wl_data_offer_add_listener(struct wl_data_offer *wl_data_offer, + const struct wl_data_offer_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_data_offer, + (void (**)(void)) listener, data); +} + +#define WL_DATA_OFFER_ACCEPT 0 +#define WL_DATA_OFFER_RECEIVE 1 +#define WL_DATA_OFFER_DESTROY 2 +#define WL_DATA_OFFER_FINISH 3 +#define WL_DATA_OFFER_SET_ACTIONS 4 + +static inline void +wl_data_offer_set_user_data(struct wl_data_offer *wl_data_offer, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_data_offer, user_data); +} + +static inline void * +wl_data_offer_get_user_data(struct wl_data_offer *wl_data_offer) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_data_offer); +} + +static inline uint32_t +wl_data_offer_get_version(struct wl_data_offer *wl_data_offer) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_data_offer); +} + +static inline void +wl_data_offer_accept(struct wl_data_offer *wl_data_offer, uint32_t serial, const char *mime_type) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_offer, + WL_DATA_OFFER_ACCEPT, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_offer), 0, serial, mime_type); +} + +static inline void +wl_data_offer_receive(struct wl_data_offer *wl_data_offer, const char *mime_type, int32_t fd) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_offer, + WL_DATA_OFFER_RECEIVE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_offer), 0, mime_type, fd); +} + +static inline void +wl_data_offer_destroy(struct wl_data_offer *wl_data_offer) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_offer, + WL_DATA_OFFER_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_offer), WL_MARSHAL_FLAG_DESTROY); +} + +static inline void +wl_data_offer_finish(struct wl_data_offer *wl_data_offer) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_offer, + WL_DATA_OFFER_FINISH, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_offer), 0); +} + +static inline void +wl_data_offer_set_actions(struct wl_data_offer *wl_data_offer, uint32_t dnd_actions, uint32_t preferred_action) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_offer, + WL_DATA_OFFER_SET_ACTIONS, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_offer), 0, dnd_actions, preferred_action); +} + +#ifndef WL_DATA_SOURCE_ERROR_ENUM +#define WL_DATA_SOURCE_ERROR_ENUM +enum wl_data_source_error { + WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK = 0, + WL_DATA_SOURCE_ERROR_INVALID_SOURCE = 1, +}; +#endif /* WL_DATA_SOURCE_ERROR_ENUM */ + +struct wl_data_source_listener { + + void (*target)(void *data, + struct wl_data_source *wl_data_source, + const char *mime_type); + + void (*send)(void *data, + struct wl_data_source *wl_data_source, + const char *mime_type, + int32_t fd); + + void (*cancelled)(void *data, + struct wl_data_source *wl_data_source); + + void (*dnd_drop_performed)(void *data, + struct wl_data_source *wl_data_source); + + void (*dnd_finished)(void *data, + struct wl_data_source *wl_data_source); + + void (*action)(void *data, + struct wl_data_source *wl_data_source, + uint32_t dnd_action); +}; + +static inline int +wl_data_source_add_listener(struct wl_data_source *wl_data_source, + const struct wl_data_source_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_data_source, + (void (**)(void)) listener, data); +} + +#define WL_DATA_SOURCE_OFFER 0 +#define WL_DATA_SOURCE_DESTROY 1 +#define WL_DATA_SOURCE_SET_ACTIONS 2 + +static inline void +wl_data_source_set_user_data(struct wl_data_source *wl_data_source, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_data_source, user_data); +} + +static inline void * +wl_data_source_get_user_data(struct wl_data_source *wl_data_source) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_data_source); +} + +static inline uint32_t +wl_data_source_get_version(struct wl_data_source *wl_data_source) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_data_source); +} + +static inline void +wl_data_source_offer(struct wl_data_source *wl_data_source, const char *mime_type) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_source, + WL_DATA_SOURCE_OFFER, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_source), 0, mime_type); +} + +static inline void +wl_data_source_destroy(struct wl_data_source *wl_data_source) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_source, + WL_DATA_SOURCE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_source), WL_MARSHAL_FLAG_DESTROY); +} + +static inline void +wl_data_source_set_actions(struct wl_data_source *wl_data_source, uint32_t dnd_actions) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_source, + WL_DATA_SOURCE_SET_ACTIONS, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_source), 0, dnd_actions); +} + +#ifndef WL_DATA_DEVICE_ERROR_ENUM +#define WL_DATA_DEVICE_ERROR_ENUM +enum wl_data_device_error { + WL_DATA_DEVICE_ERROR_ROLE = 0, + WL_DATA_DEVICE_ERROR_USED_SOURCE = 1, +}; +#endif /* WL_DATA_DEVICE_ERROR_ENUM */ + +struct wl_data_device_listener { + + void (*data_offer)(void *data, + struct wl_data_device *wl_data_device, + struct wl_data_offer *id); + + void (*enter)(void *data, + struct wl_data_device *wl_data_device, + uint32_t serial, + struct wl_surface *surface, + wl_fixed_t x, + wl_fixed_t y, + struct wl_data_offer *id); + + void (*leave)(void *data, + struct wl_data_device *wl_data_device); + + void (*motion)(void *data, + struct wl_data_device *wl_data_device, + uint32_t time, + wl_fixed_t x, + wl_fixed_t y); + + void (*drop)(void *data, + struct wl_data_device *wl_data_device); + + void (*selection)(void *data, + struct wl_data_device *wl_data_device, + struct wl_data_offer *id); +}; + +static inline int +wl_data_device_add_listener(struct wl_data_device *wl_data_device, + const struct wl_data_device_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_data_device, + (void (**)(void)) listener, data); +} + +#define WL_DATA_DEVICE_START_DRAG 0 +#define WL_DATA_DEVICE_SET_SELECTION 1 +#define WL_DATA_DEVICE_RELEASE 2 + +static inline void +wl_data_device_set_user_data(struct wl_data_device *wl_data_device, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_data_device, user_data); +} + +static inline void * +wl_data_device_get_user_data(struct wl_data_device *wl_data_device) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_data_device); +} + +static inline uint32_t +wl_data_device_get_version(struct wl_data_device *wl_data_device) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_data_device); +} + +static inline void +wl_data_device_destroy(struct wl_data_device *wl_data_device) +{ + wl_proxy_destroy((struct wl_proxy *) wl_data_device); +} + +static inline void +wl_data_device_start_drag(struct wl_data_device *wl_data_device, struct wl_data_source *source, struct wl_surface *origin, struct wl_surface *icon, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_device, + WL_DATA_DEVICE_START_DRAG, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_device), 0, source, origin, icon, serial); +} + +static inline void +wl_data_device_set_selection(struct wl_data_device *wl_data_device, struct wl_data_source *source, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_device, + WL_DATA_DEVICE_SET_SELECTION, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_device), 0, source, serial); +} + +static inline void +wl_data_device_release(struct wl_data_device *wl_data_device) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_device, + WL_DATA_DEVICE_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_device), WL_MARSHAL_FLAG_DESTROY); +} + +#ifndef WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM +#define WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM + +enum wl_data_device_manager_dnd_action { + WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE = 0, + WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY = 1, + WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE = 2, + WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK = 4, +}; +#endif /* WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM */ + +#define WL_DATA_DEVICE_MANAGER_CREATE_DATA_SOURCE 0 +#define WL_DATA_DEVICE_MANAGER_GET_DATA_DEVICE 1 + +static inline void +wl_data_device_manager_set_user_data(struct wl_data_device_manager *wl_data_device_manager, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_data_device_manager, user_data); +} + +static inline void * +wl_data_device_manager_get_user_data(struct wl_data_device_manager *wl_data_device_manager) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_data_device_manager); +} + +static inline uint32_t +wl_data_device_manager_get_version(struct wl_data_device_manager *wl_data_device_manager) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_data_device_manager); +} + +static inline void +wl_data_device_manager_destroy(struct wl_data_device_manager *wl_data_device_manager) +{ + wl_proxy_destroy((struct wl_proxy *) wl_data_device_manager); +} + +static inline struct wl_data_source * +wl_data_device_manager_create_data_source(struct wl_data_device_manager *wl_data_device_manager) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_data_device_manager, + WL_DATA_DEVICE_MANAGER_CREATE_DATA_SOURCE, wl_data_source_interface, wl_proxy_get_version((struct wl_proxy *) wl_data_device_manager), 0, NULL); + + return (struct wl_data_source *) id; +} + +static inline struct wl_data_device * +wl_data_device_manager_get_data_device(struct wl_data_device_manager *wl_data_device_manager, struct wl_seat *seat) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_data_device_manager, + WL_DATA_DEVICE_MANAGER_GET_DATA_DEVICE, wl_data_device_interface, wl_proxy_get_version((struct wl_proxy *) wl_data_device_manager), 0, NULL, seat); + + return (struct wl_data_device *) id; +} + +#ifndef WL_SHELL_ERROR_ENUM +#define WL_SHELL_ERROR_ENUM +enum wl_shell_error { + WL_SHELL_ERROR_ROLE = 0, +}; +#endif /* WL_SHELL_ERROR_ENUM */ + +#define WL_SHELL_GET_SHELL_SURFACE 0 + +#define WL_SHELL_GET_SHELL_SURFACE_SINCE_VERSION 1 + +static inline void +wl_shell_set_user_data(struct wl_shell *wl_shell, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_shell, user_data); +} + +static inline void * +wl_shell_get_user_data(struct wl_shell *wl_shell) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_shell); +} + +static inline uint32_t +wl_shell_get_version(struct wl_shell *wl_shell) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_shell); +} + +static inline void +wl_shell_destroy(struct wl_shell *wl_shell) +{ + wl_proxy_destroy((struct wl_proxy *) wl_shell); +} + +static inline struct wl_shell_surface * +wl_shell_get_shell_surface(struct wl_shell *wl_shell, struct wl_surface *surface) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_shell, + WL_SHELL_GET_SHELL_SURFACE, wl_shell_surface_interface, wl_proxy_get_version((struct wl_proxy *) wl_shell), 0, NULL, surface); + + return (struct wl_shell_surface *) id; +} + +#ifndef WL_SHELL_SURFACE_RESIZE_ENUM +#define WL_SHELL_SURFACE_RESIZE_ENUM + +enum wl_shell_surface_resize { + /** + * no edge + */ + WL_SHELL_SURFACE_RESIZE_NONE = 0, + /** + * top edge + */ + WL_SHELL_SURFACE_RESIZE_TOP = 1, + WL_SHELL_SURFACE_RESIZE_BOTTOM = 2, + WL_SHELL_SURFACE_RESIZE_LEFT = 4, + WL_SHELL_SURFACE_RESIZE_TOP_LEFT = 5, + WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT = 6, + WL_SHELL_SURFACE_RESIZE_RIGHT = 8, + WL_SHELL_SURFACE_RESIZE_TOP_RIGHT = 9, + WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT = 10, +}; +#endif /* WL_SHELL_SURFACE_RESIZE_ENUM */ + +#ifndef WL_SHELL_SURFACE_TRANSIENT_ENUM +#define WL_SHELL_SURFACE_TRANSIENT_ENUM + +enum wl_shell_surface_transient { + WL_SHELL_SURFACE_TRANSIENT_INACTIVE = 0x1, +}; +#endif /* WL_SHELL_SURFACE_TRANSIENT_ENUM */ + +#ifndef WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM +#define WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM + +enum wl_shell_surface_fullscreen_method { + WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT = 0, + WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE = 1,WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER = 2, + WL_SHELL_SURFACE_FULLSCREEN_METHOD_FILL = 3, +}; +#endif /* WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM */ + +struct wl_shell_surface_listener { + + void (*ping)(void *data, + struct wl_shell_surface *wl_shell_surface, + uint32_t serial); + + void (*configure)(void *data, + struct wl_shell_surface *wl_shell_surface, + uint32_t edges, + int32_t width, + int32_t height); + + void (*popup_done)(void *data, + struct wl_shell_surface *wl_shell_surface); +}; + +static inline int +wl_shell_surface_add_listener(struct wl_shell_surface *wl_shell_surface, + const struct wl_shell_surface_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_shell_surface, + (void (**)(void)) listener, data); +} + +#define WL_SHELL_SURFACE_PONG 0 +#define WL_SHELL_SURFACE_MOVE 1 +#define WL_SHELL_SURFACE_RESIZE 2 +#define WL_SHELL_SURFACE_SET_TOPLEVEL 3 +#define WL_SHELL_SURFACE_SET_TRANSIENT 4 +#define WL_SHELL_SURFACE_SET_FULLSCREEN 5 +#define WL_SHELL_SURFACE_SET_POPUP 6 +#define WL_SHELL_SURFACE_SET_MAXIMIZED 7 +#define WL_SHELL_SURFACE_SET_TITLE 8 +#define WL_SHELL_SURFACE_SET_CLASS 9 + +static inline void +wl_shell_surface_set_user_data(struct wl_shell_surface *wl_shell_surface, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_shell_surface, user_data); +} + +static inline void * +wl_shell_surface_get_user_data(struct wl_shell_surface *wl_shell_surface) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_shell_surface); +} + +static inline uint32_t +wl_shell_surface_get_version(struct wl_shell_surface *wl_shell_surface) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_shell_surface); +} + +static inline void +wl_shell_surface_destroy(struct wl_shell_surface *wl_shell_surface) +{ + wl_proxy_destroy((struct wl_proxy *) wl_shell_surface); +} + +static inline void +wl_shell_surface_pong(struct wl_shell_surface *wl_shell_surface, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_PONG, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, serial); +} + +static inline void +wl_shell_surface_move(struct wl_shell_surface *wl_shell_surface, struct wl_seat *seat, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_MOVE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, seat, serial); +} + +static inline void +wl_shell_surface_resize(struct wl_shell_surface *wl_shell_surface, struct wl_seat *seat, uint32_t serial, uint32_t edges) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_RESIZE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, seat, serial, edges); +} + +static inline void +wl_shell_surface_set_toplevel(struct wl_shell_surface *wl_shell_surface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_SET_TOPLEVEL, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0); +} + +static inline void +wl_shell_surface_set_transient(struct wl_shell_surface *wl_shell_surface, struct wl_surface *parent, int32_t x, int32_t y, uint32_t flags) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_SET_TRANSIENT, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, parent, x, y, flags); +} + +static inline void +wl_shell_surface_set_fullscreen(struct wl_shell_surface *wl_shell_surface, uint32_t method, uint32_t framerate, struct wl_output *output) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_SET_FULLSCREEN, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, method, framerate, output); +} + +static inline void +wl_shell_surface_set_popup(struct wl_shell_surface *wl_shell_surface, struct wl_seat *seat, uint32_t serial, struct wl_surface *parent, int32_t x, int32_t y, uint32_t flags) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_SET_POPUP, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, seat, serial, parent, x, y, flags); +} + +static inline void +wl_shell_surface_set_maximized(struct wl_shell_surface *wl_shell_surface, struct wl_output *output) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_SET_MAXIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, output); +} + +static inline void +wl_shell_surface_set_title(struct wl_shell_surface *wl_shell_surface, const char *title) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_SET_TITLE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, title); +} + +static inline void +wl_shell_surface_set_class(struct wl_shell_surface *wl_shell_surface, const char *class_) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_SET_CLASS, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, class_); +} + +#ifndef WL_SURFACE_ERROR_ENUM +#define WL_SURFACE_ERROR_ENUM + +enum wl_surface_error { + WL_SURFACE_ERROR_INVALID_SCALE = 0, + WL_SURFACE_ERROR_INVALID_TRANSFORM = 1, + WL_SURFACE_ERROR_INVALID_SIZE = 2, + WL_SURFACE_ERROR_INVALID_OFFSET = 3, + WL_SURFACE_ERROR_DEFUNCT_ROLE_OBJECT = 4, +}; +#endif /* WL_SURFACE_ERROR_ENUM */ + +struct wl_surface_listener { + + void (*enter)(void *data, + struct wl_surface *wl_surface, + struct wl_output *output); + + void (*leave)(void *data, + struct wl_surface *wl_surface, + struct wl_output *output); + + void (*preferred_buffer_scale)(void *data, + struct wl_surface *wl_surface, + int32_t factor); + + void (*preferred_buffer_transform)(void *data, + struct wl_surface *wl_surface, + uint32_t transform); +}; + +static inline int +wl_surface_add_listener(struct wl_surface *wl_surface, + const struct wl_surface_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_surface, + (void (**)(void)) listener, data); +} + +#define WL_SURFACE_DESTROY 0 +#define WL_SURFACE_ATTACH 1 +#define WL_SURFACE_DAMAGE 2 +#define WL_SURFACE_FRAME 3 +#define WL_SURFACE_SET_OPAQUE_REGION 4 +#define WL_SURFACE_SET_INPUT_REGION 5 +#define WL_SURFACE_COMMIT 6 +#define WL_SURFACE_SET_BUFFER_TRANSFORM 7 +#define WL_SURFACE_SET_BUFFER_SCALE 8 +#define WL_SURFACE_DAMAGE_BUFFER 9 +#define WL_SURFACE_OFFSET 10 + +static inline void +wl_surface_set_user_data(struct wl_surface *wl_surface, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_surface, user_data); +} + +/** @ingroup iface_wl_surface */ +static inline void * +wl_surface_get_user_data(struct wl_surface *wl_surface) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_surface); +} + +static inline uint32_t +wl_surface_get_version(struct wl_surface *wl_surface) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_surface); +} + +static inline void +wl_surface_destroy(struct wl_surface *wl_surface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), WL_MARSHAL_FLAG_DESTROY); +} + +static inline void +wl_surface_attach(struct wl_surface *wl_surface, struct wl_buffer *buffer, int32_t x, int32_t y) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_ATTACH, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, buffer, x, y); +} + +static inline void +wl_surface_damage(struct wl_surface *wl_surface, int32_t x, int32_t y, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_DAMAGE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, x, y, width, height); +} + +static inline struct wl_callback * +wl_surface_frame(struct wl_surface *wl_surface) +{ + struct wl_proxy *callback; + + callback = wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_FRAME, wl_callback_interface, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, NULL); + + return (struct wl_callback *) callback; +} + +static inline void +wl_surface_set_opaque_region(struct wl_surface *wl_surface, struct wl_region *region) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_SET_OPAQUE_REGION, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, region); +} + +static inline void +wl_surface_set_input_region(struct wl_surface *wl_surface, struct wl_region *region) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_SET_INPUT_REGION, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, region); +} + +static inline void +wl_surface_commit(struct wl_surface *wl_surface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_COMMIT, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0); +} + +static inline void +wl_surface_set_buffer_transform(struct wl_surface *wl_surface, int32_t transform) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_SET_BUFFER_TRANSFORM, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, transform); +} + +static inline void +wl_surface_set_buffer_scale(struct wl_surface *wl_surface, int32_t scale) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_SET_BUFFER_SCALE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, scale); +} + +static inline void +wl_surface_damage_buffer(struct wl_surface *wl_surface, int32_t x, int32_t y, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_DAMAGE_BUFFER, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, x, y, width, height); +} + +static inline void +wl_surface_offset(struct wl_surface *wl_surface, int32_t x, int32_t y) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_OFFSET, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, x, y); +} + +#ifndef WL_SEAT_CAPABILITY_ENUM +#define WL_SEAT_CAPABILITY_ENUM + +enum wl_seat_capability { + WL_SEAT_CAPABILITY_POINTER = 1, + WL_SEAT_CAPABILITY_KEYBOARD = 2, + WL_SEAT_CAPABILITY_TOUCH = 4, +}; +#endif /* WL_SEAT_CAPABILITY_ENUM */ + +#ifndef WL_SEAT_ERROR_ENUM +#define WL_SEAT_ERROR_ENUM + +enum wl_seat_error { + WL_SEAT_ERROR_MISSING_CAPABILITY = 0, +}; +#endif /* WL_SEAT_ERROR_ENUM */ + +struct wl_seat_listener { + + void (*capabilities)(void *data, + struct wl_seat *wl_seat, + uint32_t capabilities); + + void (*name)(void *data, + struct wl_seat *wl_seat, + const char *name); +}; + +static inline int +wl_seat_add_listener(struct wl_seat *wl_seat, + const struct wl_seat_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_seat, + (void (**)(void)) listener, data); +} + +#define WL_SEAT_GET_POINTER 0 +#define WL_SEAT_GET_KEYBOARD 1 +#define WL_SEAT_GET_TOUCH 2 +#define WL_SEAT_RELEASE 3 + +static inline void +wl_seat_set_user_data(struct wl_seat *wl_seat, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_seat, user_data); +} + +static inline void * +wl_seat_get_user_data(struct wl_seat *wl_seat) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_seat); +} + +static inline uint32_t +wl_seat_get_version(struct wl_seat *wl_seat) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_seat); +} + +static inline void +wl_seat_destroy(struct wl_seat *wl_seat) +{ + wl_proxy_destroy((struct wl_proxy *) wl_seat); +} + +static inline struct wl_pointer * +wl_seat_get_pointer(struct wl_seat *wl_seat) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_seat, + WL_SEAT_GET_POINTER, wl_pointer_interface, wl_proxy_get_version((struct wl_proxy *) wl_seat), 0, NULL); + + return (struct wl_pointer *) id; +} + +static inline struct wl_keyboard * +wl_seat_get_keyboard(struct wl_seat *wl_seat) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_seat, + WL_SEAT_GET_KEYBOARD, wl_keyboard_interface, wl_proxy_get_version((struct wl_proxy *) wl_seat), 0, NULL); + + return (struct wl_keyboard *) id; +} + +static inline struct wl_touch * +wl_seat_get_touch(struct wl_seat *wl_seat) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_seat, + WL_SEAT_GET_TOUCH, wl_touch_interface, wl_proxy_get_version((struct wl_proxy *) wl_seat), 0, NULL); + + return (struct wl_touch *) id; +} + +static inline void +wl_seat_release(struct wl_seat *wl_seat) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_seat, + WL_SEAT_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_seat), WL_MARSHAL_FLAG_DESTROY); +} + +#ifndef WL_POINTER_ERROR_ENUM +#define WL_POINTER_ERROR_ENUM +enum wl_pointer_error { + WL_POINTER_ERROR_ROLE = 0, +}; +#endif /* WL_POINTER_ERROR_ENUM */ + +#ifndef WL_POINTER_BUTTON_STATE_ENUM +#define WL_POINTER_BUTTON_STATE_ENUM + +enum wl_pointer_button_state { + WL_POINTER_BUTTON_STATE_RELEASED = 0, + WL_POINTER_BUTTON_STATE_PRESSED = 1, +}; +#endif /* WL_POINTER_BUTTON_STATE_ENUM */ + +#ifndef WL_POINTER_AXIS_ENUM +#define WL_POINTER_AXIS_ENUM + +enum wl_pointer_axis { + WL_POINTER_AXIS_VERTICAL_SCROLL = 0, + WL_POINTER_AXIS_HORIZONTAL_SCROLL = 1, +}; +#endif /* WL_POINTER_AXIS_ENUM */ + +#ifndef WL_POINTER_AXIS_SOURCE_ENUM +#define WL_POINTER_AXIS_SOURCE_ENUM + +enum wl_pointer_axis_source { + WL_POINTER_AXIS_SOURCE_WHEEL = 0, + WL_POINTER_AXIS_SOURCE_FINGER = 1, + WL_POINTER_AXIS_SOURCE_CONTINUOUS = 2, + WL_POINTER_AXIS_SOURCE_WHEEL_TILT = 3, +}; + +#define WL_POINTER_AXIS_SOURCE_WHEEL_TILT_SINCE_VERSION 6 +#endif /* WL_POINTER_AXIS_SOURCE_ENUM */ + +#ifndef WL_POINTER_AXIS_RELATIVE_DIRECTION_ENUM + +enum wl_pointer_axis_relative_direction { + WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL = 0, + WL_POINTER_AXIS_RELATIVE_DIRECTION_INVERTED = 1, +}; +#endif /* WL_POINTER_AXIS_RELATIVE_DIRECTION_ENUM */ + +struct wl_pointer_listener { + + void (*enter)(void *data, + struct wl_pointer *wl_pointer, + uint32_t serial, + struct wl_surface *surface, + wl_fixed_t surface_x, + wl_fixed_t surface_y); + + void (*leave)(void *data, + struct wl_pointer *wl_pointer, + uint32_t serial, + struct wl_surface *surface); + + void (*motion)(void *data, + struct wl_pointer *wl_pointer, + uint32_t time, + wl_fixed_t surface_x, + wl_fixed_t surface_y); + + void (*button)(void *data, + struct wl_pointer *wl_pointer, + uint32_t serial, + uint32_t time, + uint32_t button, + uint32_t state); + + void (*axis)(void *data, + struct wl_pointer *wl_pointer, + uint32_t time, + uint32_t axis, + wl_fixed_t value); + + void (*frame)(void *data, + struct wl_pointer *wl_pointer); + + void (*axis_source)(void *data, + struct wl_pointer *wl_pointer, + uint32_t axis_source); + + void (*axis_stop)(void *data, + struct wl_pointer *wl_pointer, + uint32_t time, + uint32_t axis); + + void (*axis_discrete)(void *data, + struct wl_pointer *wl_pointer, + uint32_t axis, + int32_t discrete); + + void (*axis_value120)(void *data, + struct wl_pointer *wl_pointer, + uint32_t axis, + int32_t value120); + + void (*axis_relative_direction)(void *data, + struct wl_pointer *wl_pointer, + uint32_t axis, + uint32_t direction); +}; + +static inline int +wl_pointer_add_listener(struct wl_pointer *wl_pointer, + const struct wl_pointer_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_pointer, + (void (**)(void)) listener, data); +} + +#define WL_POINTER_SET_CURSOR 0 +#define WL_POINTER_RELEASE 1 + +static inline void +wl_pointer_set_user_data(struct wl_pointer *wl_pointer, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_pointer, user_data); +} + +static inline void * +wl_pointer_get_user_data(struct wl_pointer *wl_pointer) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_pointer); +} + +static inline uint32_t +wl_pointer_get_version(struct wl_pointer *wl_pointer) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_pointer); +} + +static inline void +wl_pointer_destroy(struct wl_pointer *wl_pointer) +{ + wl_proxy_destroy((struct wl_proxy *) wl_pointer); +} + +static inline void +wl_pointer_set_cursor(struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, int32_t hotspot_x, int32_t hotspot_y) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_pointer, + WL_POINTER_SET_CURSOR, NULL, wl_proxy_get_version((struct wl_proxy *) wl_pointer), 0, serial, surface, hotspot_x, hotspot_y); +} + +static inline void +wl_pointer_release(struct wl_pointer *wl_pointer) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_pointer, + WL_POINTER_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_pointer), WL_MARSHAL_FLAG_DESTROY); +} + +#ifndef WL_KEYBOARD_KEYMAP_FORMAT_ENUM +#define WL_KEYBOARD_KEYMAP_FORMAT_ENUM + +enum wl_keyboard_keymap_format { + WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP = 0, + WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 = 1, +}; +#endif /* WL_KEYBOARD_KEYMAP_FORMAT_ENUM */ + +#ifndef WL_KEYBOARD_KEY_STATE_ENUM +#define WL_KEYBOARD_KEY_STATE_ENUM + +enum wl_keyboard_key_state { + WL_KEYBOARD_KEY_STATE_RELEASED = 0, + WL_KEYBOARD_KEY_STATE_PRESSED = 1, +}; +#endif /* WL_KEYBOARD_KEY_STATE_ENUM */ + + +struct wl_keyboard_listener { + + void (*keymap)(void *data, + struct wl_keyboard *wl_keyboard, + uint32_t format, + int32_t fd, + uint32_t size); + + void (*enter)(void *data, + struct wl_keyboard *wl_keyboard, + uint32_t serial, + struct wl_surface *surface, + struct wl_array *keys); + + void (*leave)(void *data, + struct wl_keyboard *wl_keyboard, + uint32_t serial, + struct wl_surface *surface); + + void (*key)(void *data, + struct wl_keyboard *wl_keyboard, + uint32_t serial, + uint32_t time, + uint32_t key, + uint32_t state); + + void (*modifiers)(void *data, + struct wl_keyboard *wl_keyboard, + uint32_t serial, + uint32_t mods_depressed, + uint32_t mods_latched, + uint32_t mods_locked, + uint32_t group); + + void (*repeat_info)(void *data, + struct wl_keyboard *wl_keyboard, + int32_t rate, + int32_t delay); +}; + +static inline int +wl_keyboard_add_listener(struct wl_keyboard *wl_keyboard, + const struct wl_keyboard_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_keyboard, + (void (**)(void)) listener, data); +} + +#define WL_KEYBOARD_RELEASE 0 + +static inline void +wl_keyboard_set_user_data(struct wl_keyboard *wl_keyboard, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_keyboard, user_data); +} + +static inline void * +wl_keyboard_get_user_data(struct wl_keyboard *wl_keyboard) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_keyboard); +} + +static inline uint32_t +wl_keyboard_get_version(struct wl_keyboard *wl_keyboard) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_keyboard); +} + +static inline void +wl_keyboard_destroy(struct wl_keyboard *wl_keyboard) +{ + wl_proxy_destroy((struct wl_proxy *) wl_keyboard); +} + +static inline void +wl_keyboard_release(struct wl_keyboard *wl_keyboard) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_keyboard, + WL_KEYBOARD_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_keyboard), WL_MARSHAL_FLAG_DESTROY); +} + +struct wl_touch_listener { + + void (*down)(void *data, + struct wl_touch *wl_touch, + uint32_t serial, + uint32_t time, + struct wl_surface *surface, + int32_t id, + wl_fixed_t x, + wl_fixed_t y); + + void (*up)(void *data, + struct wl_touch *wl_touch, + uint32_t serial, + uint32_t time, + int32_t id); + + void (*motion)(void *data, + struct wl_touch *wl_touch, + uint32_t time, + int32_t id, + wl_fixed_t x, + wl_fixed_t y); + + void (*frame)(void *data, + struct wl_touch *wl_touch); + + void (*cancel)(void *data, + struct wl_touch *wl_touch); + + void (*shape)(void *data, + struct wl_touch *wl_touch, + int32_t id, + wl_fixed_t major, + wl_fixed_t minor); + + void (*orientation)(void *data, + struct wl_touch *wl_touch, + int32_t id, + wl_fixed_t orientation); +}; + +/** + * @ingroup iface_wl_touch + */ +static inline int +wl_touch_add_listener(struct wl_touch *wl_touch, + const struct wl_touch_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_touch, + (void (**)(void)) listener, data); +} + +#define WL_TOUCH_RELEASE 0 + +static inline void +wl_touch_set_user_data(struct wl_touch *wl_touch, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_touch, user_data); +} + +static inline void * +wl_touch_get_user_data(struct wl_touch *wl_touch) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_touch); +} + +static inline uint32_t +wl_touch_get_version(struct wl_touch *wl_touch) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_touch); +} + +static inline void +wl_touch_destroy(struct wl_touch *wl_touch) +{ + wl_proxy_destroy((struct wl_proxy *) wl_touch); +} + +static inline void +wl_touch_release(struct wl_touch *wl_touch) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_touch, + WL_TOUCH_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_touch), WL_MARSHAL_FLAG_DESTROY); +} + +#ifndef WL_OUTPUT_SUBPIXEL_ENUM +#define WL_OUTPUT_SUBPIXEL_ENUM + +enum wl_output_subpixel { + WL_OUTPUT_SUBPIXEL_UNKNOWN = 0, + WL_OUTPUT_SUBPIXEL_NONE = 1, + WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB = 2, + WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR = 3, + WL_OUTPUT_SUBPIXEL_VERTICAL_RGB = 4, + WL_OUTPUT_SUBPIXEL_VERTICAL_BGR = 5, +}; +#endif /* WL_OUTPUT_SUBPIXEL_ENUM */ + +#ifndef WL_OUTPUT_TRANSFORM_ENUM +#define WL_OUTPUT_TRANSFORM_ENUM + +enum wl_output_transform { + WL_OUTPUT_TRANSFORM_NORMAL = 0, + WL_OUTPUT_TRANSFORM_90 = 1, + WL_OUTPUT_TRANSFORM_180 = 2, + WL_OUTPUT_TRANSFORM_270 = 3, + WL_OUTPUT_TRANSFORM_FLIPPED = 4, + WL_OUTPUT_TRANSFORM_FLIPPED_90 = 5, + WL_OUTPUT_TRANSFORM_FLIPPED_180 = 6, + WL_OUTPUT_TRANSFORM_FLIPPED_270 = 7, +}; +#endif /* WL_OUTPUT_TRANSFORM_ENUM */ + +#ifndef WL_OUTPUT_MODE_ENUM +#define WL_OUTPUT_MODE_ENUM + +enum wl_output_mode { + WL_OUTPUT_MODE_CURRENT = 0x1, + WL_OUTPUT_MODE_PREFERRED = 0x2, +}; +#endif /* WL_OUTPUT_MODE_ENUM */ + +struct wl_output_listener { + + void (*geometry)(void *data, + struct wl_output *wl_output, + int32_t x, + int32_t y, + int32_t physical_width, + int32_t physical_height, + int32_t subpixel, + const char *make, + const char *model, + int32_t transform); + + void (*mode)(void *data, + struct wl_output *wl_output, + uint32_t flags, + int32_t width, + int32_t height, + int32_t refresh); + + void (*done)(void *data, + struct wl_output *wl_output); + + void (*scale)(void *data, + struct wl_output *wl_output, + int32_t factor); + + void (*name)(void *data, + struct wl_output *wl_output, + const char *name); + + void (*description)(void *data, + struct wl_output *wl_output, + const char *description); +}; + +/** + * @ingroup iface_wl_output + */ +static inline int +wl_output_add_listener(struct wl_output *wl_output, + const struct wl_output_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_output, + (void (**)(void)) listener, data); +} + +#define WL_OUTPUT_RELEASE 0 + +static inline void +wl_output_set_user_data(struct wl_output *wl_output, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_output, user_data); +} + +static inline void * +wl_output_get_user_data(struct wl_output *wl_output) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_output); +} + +static inline uint32_t +wl_output_get_version(struct wl_output *wl_output) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_output); +} + +static inline void +wl_output_destroy(struct wl_output *wl_output) +{ + wl_proxy_destroy((struct wl_proxy *) wl_output); +} + +static inline void +wl_output_release(struct wl_output *wl_output) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_output, + WL_OUTPUT_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_output), WL_MARSHAL_FLAG_DESTROY); +} + +#define WL_REGION_DESTROY 0 +#define WL_REGION_ADD 1 +#define WL_REGION_SUBTRACT 2 + +static inline void +wl_region_set_user_data(struct wl_region *wl_region, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_region, user_data); +} + +static inline void * +wl_region_get_user_data(struct wl_region *wl_region) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_region); +} + +static inline uint32_t +wl_region_get_version(struct wl_region *wl_region) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_region); +} + +static inline void +wl_region_destroy(struct wl_region *wl_region) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_region, + WL_REGION_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_region), WL_MARSHAL_FLAG_DESTROY); +} + +static inline void +wl_region_add(struct wl_region *wl_region, int32_t x, int32_t y, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_region, + WL_REGION_ADD, NULL, wl_proxy_get_version((struct wl_proxy *) wl_region), 0, x, y, width, height); +} + +static inline void +wl_region_subtract(struct wl_region *wl_region, int32_t x, int32_t y, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_region, + WL_REGION_SUBTRACT, NULL, wl_proxy_get_version((struct wl_proxy *) wl_region), 0, x, y, width, height); +} + +#ifndef WL_SUBCOMPOSITOR_ERROR_ENUM +#define WL_SUBCOMPOSITOR_ERROR_ENUM +enum wl_subcompositor_error { + /** + * the to-be sub-surface is invalid + */ + WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE = 0, + /** + * the to-be sub-surface parent is invalid + */ + WL_SUBCOMPOSITOR_ERROR_BAD_PARENT = 1, +}; +#endif /* WL_SUBCOMPOSITOR_ERROR_ENUM */ + +#define WL_SUBCOMPOSITOR_DESTROY 0 +#define WL_SUBCOMPOSITOR_GET_SUBSURFACE 1 + +static inline void +wl_subcompositor_set_user_data(struct wl_subcompositor *wl_subcompositor, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_subcompositor, user_data); +} + +static inline void * +wl_subcompositor_get_user_data(struct wl_subcompositor *wl_subcompositor) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_subcompositor); +} + +static inline uint32_t +wl_subcompositor_get_version(struct wl_subcompositor *wl_subcompositor) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_subcompositor); +} + +static inline void +wl_subcompositor_destroy(struct wl_subcompositor *wl_subcompositor) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_subcompositor, + WL_SUBCOMPOSITOR_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subcompositor), WL_MARSHAL_FLAG_DESTROY); +} + +static inline struct wl_subsurface * +wl_subcompositor_get_subsurface(struct wl_subcompositor *wl_subcompositor, struct wl_surface *surface, struct wl_surface *parent) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_subcompositor, + WL_SUBCOMPOSITOR_GET_SUBSURFACE, wl_subsurface_interface, wl_proxy_get_version((struct wl_proxy *) wl_subcompositor), 0, NULL, surface, parent); + + return (struct wl_subsurface *) id; +} + +#ifndef WL_SUBSURFACE_ERROR_ENUM +#define WL_SUBSURFACE_ERROR_ENUM +enum wl_subsurface_error { + WL_SUBSURFACE_ERROR_BAD_SURFACE = 0, +}; +#endif /* WL_SUBSURFACE_ERROR_ENUM */ + +#define WL_SUBSURFACE_DESTROY 0 +#define WL_SUBSURFACE_SET_POSITION 1 +#define WL_SUBSURFACE_PLACE_ABOVE 2 +#define WL_SUBSURFACE_PLACE_BELOW 3 +#define WL_SUBSURFACE_SET_SYNC 4 +#define WL_SUBSURFACE_SET_DESYNC 5 + +static inline void +wl_subsurface_set_user_data(struct wl_subsurface *wl_subsurface, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_subsurface, user_data); +} + +static inline void * +wl_subsurface_get_user_data(struct wl_subsurface *wl_subsurface) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_subsurface); +} + +static inline uint32_t +wl_subsurface_get_version(struct wl_subsurface *wl_subsurface) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_subsurface); +} + +static inline void +wl_subsurface_destroy(struct wl_subsurface *wl_subsurface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, + WL_SUBSURFACE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), WL_MARSHAL_FLAG_DESTROY); +} + +static inline void +wl_subsurface_set_position(struct wl_subsurface *wl_subsurface, int32_t x, int32_t y) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, + WL_SUBSURFACE_SET_POSITION, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), 0, x, y); +} + +static inline void +wl_subsurface_place_above(struct wl_subsurface *wl_subsurface, struct wl_surface *sibling) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, + WL_SUBSURFACE_PLACE_ABOVE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), 0, sibling); +} + +static inline void +wl_subsurface_place_below(struct wl_subsurface *wl_subsurface, struct wl_surface *sibling) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, + WL_SUBSURFACE_PLACE_BELOW, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), 0, sibling); +} + +static inline void +wl_subsurface_set_sync(struct wl_subsurface *wl_subsurface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, + WL_SUBSURFACE_SET_SYNC, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), 0); +} + +static inline void +wl_subsurface_set_desync(struct wl_subsurface *wl_subsurface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, + WL_SUBSURFACE_SET_DESYNC, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), 0); +} + +#endif // FENNEC_PLATFORM_LINUX_WAYLAND_SYM_DEF_H diff --git a/include/fennec/platform/linux/wayland/lib/wayland-util.h b/include/fennec/platform/linux/wayland/lib/wayland-util.h new file mode 100644 index 0000000..95ff0bb --- /dev/null +++ b/include/fennec/platform/linux/wayland/lib/wayland-util.h @@ -0,0 +1,198 @@ +// ===================================================================================================================== +// 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 . +// ===================================================================================================================== + +#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 +#include +#include + +#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 diff --git a/include/fennec/platform/linux/wayland/window.h b/include/fennec/platform/linux/wayland/window.h index 7525b8c..fca8830 100644 --- a/include/fennec/platform/linux/wayland/window.h +++ b/include/fennec/platform/linux/wayland/window.h @@ -19,13 +19,40 @@ #ifndef FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H #define FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H +#include + +#include +#include + namespace fennec { -class wayland_window { +class wayland_window : 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 set_size(size_t w, size_t h) override; + bool set_fullscreen_mode(fullscreen_mode mode) override; + bool set_resizable(bool e) 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; private: + wl_surface* _surface; + wl_shell_surface* _shell; + wl_callback* _callback; + gfxcontext* _context; }; } diff --git a/include/fennec/platform/opengl/egl/context.h b/include/fennec/platform/opengl/egl/context.h new file mode 100644 index 0000000..ea2726f --- /dev/null +++ b/include/fennec/platform/opengl/egl/context.h @@ -0,0 +1,44 @@ +// ===================================================================================================================== +// 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 . +// ===================================================================================================================== + +#ifndef FENNEC_PLATFORM_EGL_CONTEXT_H +#define FENNEC_PLATFORM_EGL_CONTEXT_H + +#include +#include +#include + +#if FENNEC_HAS_WAYLAND +#include +#endif + +namespace fennec +{ + +class eglcontext : gfxcontext { +public: + eglcontext(displaydev* device); + + EGLDisplay display; + EGLContext context; + EGLConfig config; +}; + +} + +#endif // FENNEC_PLATFORM_EGL_CONTEXT_H diff --git a/include/fennec/platform/opengl/egl/surface.h b/include/fennec/platform/opengl/egl/surface.h new file mode 100644 index 0000000..2a76d0d --- /dev/null +++ b/include/fennec/platform/opengl/egl/surface.h @@ -0,0 +1,43 @@ +// ===================================================================================================================== +// 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 . +// ===================================================================================================================== + +#ifndef FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H +#define FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H + +#include + +#include +#include + +#if FENNEC_HAS_WAYLAND + +#endif + +namespace fennec +{ + +class eglsurface : gfxsurface { +public: + eglsurface(eglcontext* context); + + EGLSurface surface; +}; + +} + +#endif // FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H diff --git a/source/platform/linux/wayland/display.cpp b/source/core/event.cpp similarity index 56% rename from source/platform/linux/wayland/display.cpp rename to source/core/event.cpp index 0fea351..8e989a3 100644 --- a/source/platform/linux/wayland/display.cpp +++ b/source/core/event.cpp @@ -16,38 +16,32 @@ // along with this program. If not, see . // ===================================================================================================================== -#include -#include -#include +#include +#include +#include namespace fennec { -wayland_display::wayland_display(linux_platform* platform) - : display() - , _handle() - , _platform(platform) { - libwayland::load_symbols(_platform); - _handle = wl_display_connect(nullptr); +static dynarray> listeners; + +void event::add_listener(event_listener* listener, uint64_t type) { + if (listeners.size() <= type) { + listeners.resize(type + 1); + } + listeners[type].insert(listener); } -wayland_display::wayland_display(linux_platform* platform, const cstring& drv) - : display() - , _handle() - , _platform(platform) { - libwayland::load_symbols(_platform); - _handle = wl_display_connect(drv); +void event::remove_listener(event_listener* listener) { + for (auto& it : listeners) { + it.erase(listener); + } } -wayland_display::~wayland_display() { - wl_display_disconnect(_handle); - libwayland::unload_symbols(_platform); - _handle = nullptr; - _platform = nullptr; +void event::dispatch(event* event) { + for (auto& it : listeners[event->type]) { + it->handle_event(event); + } } -bool wayland_display::connected() const { - return _handle != nullptr; } - -} \ No newline at end of file diff --git a/source/fproc/filesystem/file.cpp b/source/fproc/filesystem/file.cpp index 083d7c3..d65b605 100644 --- a/source/fproc/filesystem/file.cpp +++ b/source/fproc/filesystem/file.cpp @@ -24,7 +24,7 @@ #include -#ifdef _MSC_VER +#ifdef FENNEC_COMPILER_MSVC diff --git a/source/fproc/filesystem/path.cpp b/source/fproc/filesystem/path.cpp index 844121c..b1f61c0 100644 --- a/source/fproc/filesystem/path.cpp +++ b/source/fproc/filesystem/path.cpp @@ -22,7 +22,7 @@ namespace fennec { -#ifdef _MSC_VER +#ifdef FENNEC_COMPILER_MSVC path path::current() { char cstr[MAX_PATH]; diff --git a/source/memory/new.cpp b/source/memory/new.cpp index b03b997..f313dd0 100644 --- a/source/memory/new.cpp +++ b/source/memory/new.cpp @@ -29,7 +29,7 @@ #else // Windows does not define ISO C aligned allocation functions -#ifdef _MSC_VER +#ifdef FENNEC_COMPILER_MSVC void operator delete (void* ptr) noexcept { _aligned_free(ptr); } void operator delete[](void* ptr) noexcept { _aligned_free(ptr); } void operator delete (void* ptr, fennec::align_t) noexcept { ::_aligned_free(ptr); } diff --git a/source/platform/interface/displaydev.cpp b/source/platform/interface/displaydev.cpp new file mode 100644 index 0000000..6f509a2 --- /dev/null +++ b/source/platform/interface/displaydev.cpp @@ -0,0 +1,37 @@ +// ===================================================================================================================== +// fennec, a free and open source game engine +// Copyright © 2025 Medusa Slockbower +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ===================================================================================================================== + +#include + +namespace fennec +{ + +displaydev::displaydev(platform* platform) + : _platform(platform) + , _context(nullptr) + , _config { + .format = { + .depth = 24, + .r = 8, + .g = 8, + .b = 8 + } + } { +} + +} diff --git a/source/platform/interface/gfxcontext.cpp b/source/platform/interface/gfxcontext.cpp new file mode 100644 index 0000000..7704a0a --- /dev/null +++ b/source/platform/interface/gfxcontext.cpp @@ -0,0 +1,30 @@ +// ===================================================================================================================== +// fennec, a free and open source game engine +// Copyright © 2025 Medusa Slockbower +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ===================================================================================================================== + +#include + +namespace fennec +{ + +gfxcontext::gfxcontext(displaydev* device) + : _device(device) { + +} + +} + diff --git a/source/platform/interface/gfxsurface.cpp b/source/platform/interface/gfxsurface.cpp new file mode 100644 index 0000000..f098fcf --- /dev/null +++ b/source/platform/interface/gfxsurface.cpp @@ -0,0 +1,28 @@ +// ===================================================================================================================== +// fennec, a free and open source game engine +// Copyright © 2025 Medusa Slockbower +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ===================================================================================================================== + +#include + +namespace fennec +{ + +gfxsurface::gfxsurface(window* window, gfxcontext* context) + : _window(window), _context(context) { +} + +} diff --git a/source/platform/interface/platform.cpp b/source/platform/interface/platform.cpp index 368569a..c5c3402 100644 --- a/source/platform/interface/platform.cpp +++ b/source/platform/interface/platform.cpp @@ -27,8 +27,7 @@ string platform::get_environment_variable(const cstring& var) { return string(val, strlen(val)); } -platform::platform(user t) { - _config.type = t; +platform::platform() { } } diff --git a/source/platform/interface/window.cpp b/source/platform/interface/window.cpp index 3f42aca..250a252 100644 --- a/source/platform/interface/window.cpp +++ b/source/platform/interface/window.cpp @@ -21,15 +21,10 @@ namespace fennec { -window::window(display* display, window* parent, bool modal) +window::window(displaydev* display, window* parent) : _display(display) , _parent(parent) , _config() { - - bool child = parent != nullptr; - assert(!modal || child, "Attempted to create non-child modal window."); - _config.flags |= child ? flags_child : flags_none; - _config.flags |= modal ? flags_modal : flags_none; } } diff --git a/source/platform/linux/platform.cpp b/source/platform/linux/platform.cpp index aac3c01..bb29e88 100644 --- a/source/platform/linux/platform.cpp +++ b/source/platform/linux/platform.cpp @@ -22,24 +22,20 @@ #ifdef FENNEC_LIB_WAYLAND #include -#include +#include #endif namespace fennec { -linux_platform::linux_platform(user _type) - : platform(_type) +linux_platform::linux_platform() + : platform() , _display_driver(display_none) { - switch (_type) { - case user::client: { - _runtime_client_checks(); - return; - } - case user::server: { - _runtime_server_checks(); - } - } +#if FENNEC_BUILD_SERVER + _runtime_server_checks(); +#else + _runtime_client_checks(); +#endif } linux_platform::~linux_platform() { @@ -72,7 +68,17 @@ platform::function_pointer linux_platform::find_symbol(shared_object* hndl, cons return (function_pointer)symbol; } -display* linux_platform::get_display() { +platform::global linux_platform::find_global(shared_object* hndl, const cstring& name) { + string _name = name; + void* symbol = dlsym(hndl, _name); + if (symbol == nullptr) { + _name = '_' + _name; + symbol = dlsym(hndl, _name); + } + return symbol; +} + +displaydev* linux_platform::get_display() { return _display; } @@ -82,7 +88,7 @@ void linux_platform::_runtime_client_checks() { _display_driver = display_wayland; _display = new wayland_display(this); libwayland::unload_symbols(this); // Doesn't actually unload symbols, just resets ref counter to only consider - // the created display + // the created display } #endif assertf(_display != nullptr, "failed to find suitable display driver"); diff --git a/source/platform/linux/wayland/displaydev.cpp b/source/platform/linux/wayland/displaydev.cpp new file mode 100644 index 0000000..477f27e --- /dev/null +++ b/source/platform/linux/wayland/displaydev.cpp @@ -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 . +// ===================================================================================================================== + +#include +#include + +#include +#include + +namespace fennec +{ + +wayland_display::wayland_display(linux_platform* platform) + : wayland_display(platform, nullptr) { +} + +wayland_display::wayland_display(linux_platform* platform, const cstring& drv) + : displaydev(platform) + , _handle(nullptr) + , _registry(nullptr) + , _compositor(nullptr) { + + static constexpr wl_registry_listener listener = { + listen_global, listen_global_remove + }; + + // Load libwayland.so + libwayland::load_symbols(get_platform()); + + // Get handles + _handle = wl_display_connect(drv); + _registry = wl_display_get_registry(_handle); + wl_registry_add_listener(_registry, &listener, this); +} + +wayland_display::~wayland_display() { + wl_registry_destroy(_registry); + wl_display_flush(_handle); + wl_display_disconnect(_handle); + libwayland::unload_symbols(get_platform()); + _handle = nullptr; + _platform = nullptr; + for (const auto it : _windows) { + delete it; + } +} + +bool wayland_display::connected() const { + return _handle != nullptr; +} + +window* wayland_display::create_window() { + _windows.push_back(new wayland_window(this, nullptr)); + return (window*)(_windows.back()); +} + +void wayland_display::listen_global(void* data, wl_registry* registry, uint32_t name, const char* itfc, uint32_t version) { + static constexpr wl_seat_listener seat_listener = { + listen_seat, nullptr + }; + + wayland_display* device = static_cast(data); + const cstring interface = cstring(itfc, strlen(itfc) + 1); + + if (interface == "wl_compositor") { + device->_compositor = static_cast(wl_registry_bind(registry, name, wl_compositor_interface, version)); + } else if (interface == "wl_shell") { + device->_shell = static_cast(wl_registry_bind(registry, name, wl_shell_interface, version)); + } else if (interface == "wl_seat") { + device->_seat = static_cast(wl_registry_bind(registry, name, wl_seat_interface, version)); + wl_seat_add_listener(device->_seat, &seat_listener, device); + } + +} + +void wayland_display::listen_global_remove(void*, wl_registry*, uint32_t) { +} + +void wayland_display::listen_seat(void*, wl_seat*, uint32_t) { + +} + +} diff --git a/source/platform/linux/wayland/lib/dyn.cpp b/source/platform/linux/wayland/lib/dyn.cpp index 7787b62..d3fdb29 100644 --- a/source/platform/linux/wayland/lib/dyn.cpp +++ b/source/platform/linux/wayland/lib/dyn.cpp @@ -16,7 +16,7 @@ // along with this program. If not, see . // ===================================================================================================================== -#include +#include #include namespace fennec @@ -31,7 +31,6 @@ static int _load_count = 0; // Create private variables #define FENNEC_LIB(lib) static shared_lib _FENNEC_LIB_##lib = { nullptr, FENNEC_LIB_##lib }; -#define FENNEC_SYMBOL(...) #include bool load_symbols(linux_platform* platform) { @@ -39,14 +38,20 @@ bool load_symbols(linux_platform* platform) { return true; } + shared_lib* current_lib = nullptr; #define FENNEC_LIB(lib) _FENNEC_LIB_##lib._lib = platform->load_object(_FENNEC_LIB_##lib._name); \ FENNEC_HAS_LIB_##lib = _FENNEC_LIB_##lib._lib != nullptr; \ if(not FENNEC_HAS_LIB_##lib) { \ unload_symbols(platform); \ return false; \ } \ - shared_lib& current_lib = _FENNEC_LIB_##lib; -#define FENNEC_SYMBOL(ret, fn, ...) fn = (sym_##fn)(platform->find_symbol(current_lib._lib, #fn)); + current_lib = &_FENNEC_LIB_##lib; +#define FENNEC_SYMBOL(ret, fn, ...) fn = (sym_##fn)(platform->find_symbol(current_lib->_lib, #fn)); \ + assertf(fn != nullptr, "Failed to find symbol: " #fn); +#define FENNEC_GLOBAL(type, name) name = (type*)(platform->find_symbol(current_lib->_lib, #name)); \ + assertf(name != nullptr, "Failed to find global: " #name); + + #include return true; @@ -60,6 +65,7 @@ void unload_symbols(linux_platform* platform) { #define FENNEC_LIB(lib) platform->unload_object(_FENNEC_LIB_##lib._lib); \ _FENNEC_LIB_##lib._lib = nullptr; #define FENNEC_SYMBOL(ret, fn, ...) fn = nullptr; +#define FENNEC_GLOBAL(type, name) name = nullptr; #include } diff --git a/source/platform/linux/wayland/window.cpp b/source/platform/linux/wayland/window.cpp new file mode 100644 index 0000000..68166d3 --- /dev/null +++ b/source/platform/linux/wayland/window.cpp @@ -0,0 +1,86 @@ +// ===================================================================================================================== +// fennec, a free and open source game engine +// Copyright © 2025 Medusa Slockbower +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ===================================================================================================================== + +#include +#include + +#include + +namespace fennec +{ +bool wayland_window::running() { + return false; +} + +void wayland_window::configure(const config& config) { + assertf(running() == false, "Attempted to Configure Running Window."); + + _config = config; +} + +bool wayland_window::initialize(bool modal) { + assertf(_config, "Attempted to Initialize a Window Without Configuration"); + if (not _config) { + return true; + } + + _config->flags &= ~flags_modal & ~flags_child; + if (_parent != nullptr) { + _config->flags |= flags_child; + if (modal) { + _config->flags |= flags_modal; + } + } + + _surface = wl_compositor_create_surface(get_display()->get_compositor()); + _shell = wl_shell_get_shell_surface(get_display()->get_shell(), _surface); + + + return false; +} + +bool wayland_window::shutdown() { + wl_shell_surface_destroy(_shell); + wl_surface_destroy(_surface); + return false; +} + + +bool wayland_window::set_title(const cstring&) { return true; } +bool wayland_window::set_title(const string&) { return true; } +bool wayland_window::set_width(size_t) { return true; } +bool wayland_window::set_height(size_t) { return true; } +bool wayland_window::set_size(size_t, size_t) { return true; } +bool wayland_window::set_fullscreen_mode(fullscreen_mode) { return true; } +bool wayland_window::set_resizable(bool) { return true; } +bool wayland_window::grab_keyboard(bool) { return true; } +bool wayland_window::grab_mouse(bool) { return true; } +bool wayland_window::block_screensaver(bool) { return true; } + +wayland_window::wayland_window(wayland_display* display, wayland_window* parent) + : window(display, parent) + , _surface(nullptr) + , _shell(nullptr) + , _callback(nullptr) { +} + +wayland_window::~wayland_window() { + +} + +} diff --git a/test/tests/containers/test_dynarray.h b/test/tests/containers/test_dynarray.h index 928f903..6884ca9 100644 --- a/test/tests/containers/test_dynarray.h +++ b/test/tests/containers/test_dynarray.h @@ -32,7 +32,6 @@ namespace fennec::test dynarray test2; int n = 10000; - test1.resize(n); test2.resize(n); for (int i = 0; i < n; ++i) { test1.push_back(i); test2.push_back(n - i - 1); diff --git a/test/tests/platform/linux/test_wayland.h b/test/tests/platform/linux/test_wayland.h index bd3a291..df76a48 100644 --- a/test/tests/platform/linux/test_wayland.h +++ b/test/tests/platform/linux/test_wayland.h @@ -20,7 +20,7 @@ #define FENNEC_TEST_PLATFORM_LINUX_WAYLAND_H #include "../../../test.h" -#include +#include namespace fennec::test { diff --git a/test/tests/platform/test_linux.h b/test/tests/platform/test_linux.h index 727a5d8..a382553 100644 --- a/test/tests/platform/test_linux.h +++ b/test/tests/platform/test_linux.h @@ -29,7 +29,7 @@ namespace fennec::test inline void fennec_test_platform_linux() { - linux_platform platform(platform::user::client); + linux_platform platform; #ifdef FENNEC_LIB_WAYLAND fennec_test_section("wayland tests");