diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..90314ef --- /dev/null +++ b/.clang-format @@ -0,0 +1,65 @@ +--- +Language: Cpp +BasedOnStyle: LLVM + +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: true +AlignConsecutiveAssignments: true +AlignEscapedNewlines: Right +AlignOperands: false +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: false +BreakConstructorInitializers: AfterColon +ColumnLimit: 180 +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: false +IncludeBlocks: Preserve +IndentCaseLabels: true +IndentWidth: 4 +PointerAlignment: Left +ReflowComments: false +SortIncludes: false +SortUsingDeclarations: false +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +TabWidth: 4 +UseTab: Never + +AllowShortEnumsOnASingleLine: false + +BraceWrapping: + AfterEnum: false + +AlignConsecutiveDeclarations: AcrossEmptyLines + +NamespaceIndentation: All diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2c633ed --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +build/ +.vscode/ +.cache/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..fda3316 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,50 @@ +cmake_minimum_required(VERSION 3.19) + +set(AQUAMARINE_VERSION "0.1.0") +add_compile_definitions(AQUAMARINE_VERSION="${AQUAMARINE_VERSION}") + +project(aquamarine + VERSION ${AQUAMARINE_VERSION} + DESCRIPTION "A very light linux rendering backend library" +) + +include(CTest) +include(GNUInstallDirs) + +set(PREFIX ${CMAKE_INSTALL_PREFIX}) +set(INCLUDE ${CMAKE_INSTALL_FULL_INCLUDEDIR}) +set(LIBDIR ${CMAKE_INSTALL_FULL_LIBDIR}) + +find_package(PkgConfig REQUIRED) +pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-client wayland-protocols hyprutils>=0.1.2) + +configure_file(aquamarine.pc.in aquamarine.pc @ONLY) + +set(CMAKE_CXX_STANDARD 23) + +if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG) + message(STATUS "Configuring aquamarine in Debug") + add_compile_definitions(AQUAMARINE_DEBUG) +else() + add_compile_options(-O3) + message(STATUS "Configuring aquamarine in Release") +endif() + +file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp" "include/*.hpp") +file(GLOB_RECURSE PUBLIC_HEADERS CONFIGURE_DEPENDS "include/*.hpp") + +add_library(aquamarine SHARED ${SRCFILES}) +target_include_directories( aquamarine + PUBLIC "./include" + PRIVATE "./src" +) +set_target_properties(aquamarine PROPERTIES + VERSION ${AQUAMARINE_VERSION} + SOVERSION 0 +) +target_link_libraries(aquamarine PkgConfig::deps) + +# Installation +install(TARGETS aquamarine) +install(DIRECTORY "include/aquamarine" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(FILES ${CMAKE_BINARY_DIR}/aquamarine.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) diff --git a/README.md b/README.md index 6136354..c4e841f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,27 @@ -# aquamarine -Aquamarine is a very light rendering backend library +## Aquamarine + +Aquamarine is a very light linux rendering backend library. It provides basic abstractions +for an application to render on a Wayland session (in a window) or a native DRM session. + +It is agnostic of the rendering API (Vulkan/OpenGL) and designed to be lightweight, performant, and +minimal. + +## Stability + +Aquamarine depends on the ABI stability of the stdlib implementation of your compiler. Sover bumps will be done only for aquamarine ABI breaks, not stdlib. + +## Building + +```sh +cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build +cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf _NPROCESSORS_CONF` +``` + +## TODOs + + - [ ] Wayland backend + - [ ] DRM backend (DRM / KMS / libinput) + - [ ] Virtual backend (aka. Headless) + - [ ] Hardware plane support + + diff --git a/aquamarine.pc.in b/aquamarine.pc.in new file mode 100644 index 0000000..a715b45 --- /dev/null +++ b/aquamarine.pc.in @@ -0,0 +1,10 @@ +prefix=@PREFIX@ +includedir=@INCLUDE@ +libdir=@LIBDIR@ + +Name: aquamarine +URL: https://github.com/hyprwm/aquamarine +Description: A very light linux rendering backend library +Version: @AQUAMARINE_VERSION@ +Cflags: -I${includedir} +Libs: -L${libdir} -laquamarine diff --git a/include/aquamarine/backend/Backend.hpp b/include/aquamarine/backend/Backend.hpp new file mode 100644 index 0000000..1e1affd --- /dev/null +++ b/include/aquamarine/backend/Backend.hpp @@ -0,0 +1,72 @@ +#pragma once + +#include +#include +#include + +namespace Aquamarine { + enum eBackendType { + AQ_BACKEND_WAYLAND = 0, + AQ_BACKEND_DRM, + AQ_BACKEND_HEADLESS, + }; + + enum eBackendRequestMode { + /* + Require the provided backend, will error out if it's not available. + */ + AQ_BACKEND_REQUEST_MANDATORY = 0, + /* + Start the backend if it's available + */ + AQ_BACKEND_REQUEST_IF_AVAILABLE, + /* + If any IF_AVAILABLE backend fails, use this one + */ + AQ_BACKEND_REQUEST_FALLBACK, + }; + + enum eBackendLogLevel { + AQ_LOG_TRACE = 0, + AQ_LOG_DEBUG, + AQ_LOG_WARNING, + AQ_LOG_ERROR, + AQ_LOG_CRITICAL, + }; + + struct SBackendImplementationOptions { + explicit SBackendImplementationOptions(); + eBackendType backendType; + eBackendRequestMode backendRequestMode; + }; + + struct SBackendOptions { + explicit SBackendOptions(); + std::function logFunction; + }; + + class IBackendImplementation { + public: + virtual ~IBackendImplementation(); + virtual eBackendType type() = 0; + }; + + class CBackend { + public: + /* Create a backend, with the provided options. May return a single or a multi-backend. */ + static Hyprutils::Memory::CSharedPointer create(const std::vector& backends, const SBackendOptions& options); + + ~CBackend(); + + /* start the backend. Initializes all the stuff, and will return true on success, false on fail. */ + bool start(); + + void log(eBackendLogLevel level, const std::string& msg); + + private: + CBackend(); + + std::vector implementations; + SBackendOptions options; + }; +}; \ No newline at end of file diff --git a/include/aquamarine/input/Input.hpp b/include/aquamarine/input/Input.hpp new file mode 100644 index 0000000..36f92ce --- /dev/null +++ b/include/aquamarine/input/Input.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include + +struct libinput_device; + +namespace Aquamarine { + class IKeyboard { + public: + virtual libinput_device* getLibinputHandle(); + + struct { + Hyprutils::Signal::CSignal destroy; + Hyprutils::Signal::CSignal key; + Hyprutils::Signal::CSignal modifiers; + } events; + }; + + class IPointer { + public: + virtual libinput_device* getLibinputHandle(); + + struct { + Hyprutils::Signal::CSignal destroy; + Hyprutils::Signal::CSignal move; + Hyprutils::Signal::CSignal warp; + Hyprutils::Signal::CSignal button; + Hyprutils::Signal::CSignal axis; + } events; + }; +} \ No newline at end of file diff --git a/src/backend/Backend.cpp b/src/backend/Backend.cpp new file mode 100644 index 0000000..b3aba98 --- /dev/null +++ b/src/backend/Backend.cpp @@ -0,0 +1,35 @@ +#include + +using namespace Hyprutils::Memory; +using namespace Aquamarine; +#define SP CSharedPointer + +Aquamarine::CBackend::CBackend() { + ; +} + +Hyprutils::Memory::CSharedPointer Aquamarine::CBackend::create(const std::vector& backends, const SBackendOptions& options) { + auto backend = SP(new CBackend()); + + backend->options = options; + + backend->log(AQ_LOG_DEBUG, "Hello world!\n"); + + return backend; +} + +Aquamarine::CBackend::~CBackend() { + log(AQ_LOG_DEBUG, "Bye world!\n"); +} + +bool Aquamarine::CBackend::start() { + log(AQ_LOG_DEBUG, "Starting world!\n"); + return true; +} + +void Aquamarine::CBackend::log(eBackendLogLevel level, const std::string& msg) { + if (!options.logFunction) + return; + + options.logFunction(level, msg); +} diff --git a/src/input/Input.cpp b/src/input/Input.cpp new file mode 100644 index 0000000..4541b9a --- /dev/null +++ b/src/input/Input.cpp @@ -0,0 +1,9 @@ +#include + +libinput_device* Aquamarine::IPointer::getLibinputHandle() { + return nullptr; +} + +libinput_device* Aquamarine::IKeyboard::getLibinputHandle() { + return nullptr; +}